【问题标题】:I can't find the files I uploaded to Google Drive我找不到上传到 Google 云端硬盘的文件
【发布时间】:2019-06-23 18:05:03
【问题描述】:

我正在尝试使用Google Drive REST API v3 将文件上传到Google Drive。上传过程完成后,返回一个status code of 200(成功)。但我在Google Drive 中找不到这些文件。请告诉我我做错了什么?如果您在帮助我解决我的这个问题的同时提供适当的说明或更好的代码 sn-p,我将不胜感激。我真的很期待你的回答。 我已尝试按照文档进行操作,但仍然遇到相同的错误。我在网上和 stackoverflow 到处搜索,但似乎没有一个能解决我的问题。 这是代码

 private val AUTHORIZATION_PARAM = "Authorization"
    private val BEARER_VAL = "Bearer "
    private val CONTENT_TYPE_PARAM = "Content-Type: "
    private val LINE_FEED = "\r\n"
    private val APP_FOLDER_ID = "appDataFolder"



    fun connectAndStartOperation() {
        if (mAuthCode == null) {
            signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .requestProfile()
                .requestScopes(Scope(Scopes.DRIVE_APPFOLDER))
                .requestIdToken(resources.getString(R.string.gdrive_clientId))
                .requestServerAuthCode(resources.getString(R.string.gdrive_clientId))
                .build()

            mGoogleSignInClient = GoogleSignIn.getClient(this, signInOptions!!)


            startActivityForResult(mGoogleSignInClient?.signInIntent, CLOUD_STORAGE)


            Log.i("mAuthCode", "false")
        } else {
            Log.i("mAuthCode", "true")
            writeDbToDrive()
            mNextGoogleApiOperation = INVALID;
        }
    }


    fun disconnect() {
        mGoogleSignInClient?.signOut()
        mActivity = null
        mNextGoogleApiOperation = INVALID
        mAuthCode = null
        mAccessToken = null
        mTokenExpired = 0
    }

    override fun onDestroy() {
        disconnect()
        super.onDestroy()

    }

    public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == CLOUD_STORAGE) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
                .addOnSuccessListener(this)
                .addOnFailureListener(this)


        }
    }

    override fun onSuccess(googleSignInAccount: GoogleSignInAccount?) {


        Log.i("mAuthCode", "Success")
        val scope = "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile"

        idTokenString = googleSignInAccount?.idToken
        mAuthCode = googleSignInAccount?.serverAuthCode
        mGoogleSignInAccount = googleSignInAccount

        doAsync {
            try {
                mAccessToken = GoogleAuthUtil.getToken(this@SettingsActivity, mGoogleSignInAccount?.account, scope)
            } catch (e: Exception) {
                Log.i("Error AccessToken", "${e.message}")

                e.printStackTrace()
            }

            uiThread {
                Log.i("AccessTokenMy", "$mAccessToken")
            }
        }


    }


    override fun onFailure(p0: java.lang.Exception) {
        Log.i("mAuthCode", "Failed")

        p0.printStackTrace()
    }


    private fun writeDbToDrive() {
        var conn: HttpURLConnection? = null
        var os: OutputStream? = null


        val accessToken = requestAccessToken(mGoogleSignInAccount!!)

        if (accessToken == null)
            return



        try {
            val boundary = "pb" + System.currentTimeMillis()
            val url = URL("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart")
            conn = url.openConnection() as HttpURLConnection
            conn.requestMethod = "POST"
            conn.useCaches = false
            conn.doOutput = true
            conn.doInput = true
            conn.connectTimeout = 5000
            conn.setRequestProperty(AUTHORIZATION_PARAM, BEARER_VAL + accessToken!!)
            conn.setRequestProperty("Content-Type", "multipart/related; boundary=$boundary")

            Log.i("Action", "Parameter set for server")

            /////// Prepare data
            //val timestamp = SimpleDateFormat("yyyy-MM-dd_HH:mm:ss", Locale.getDefault()).format(Date())
            // Prepare file metadata (Change your backup file name here)
            val b = StringBuilder()
            b.append('{')
                .append("\"name\":\"").append(exportedFileName).append('\"')
                .append(',')
                .append("\"mimeType\":").append("\"text\\/csv\"")
                .append(',') //"\"application\\/vnd.google-apps.unknown\""
                .append("\"parents\":").append("[\"").append(APP_FOLDER_ID).append("\"]")
                .append('}')
            val metadata = b.toString()
            val data = readFile(File(filePath))

            /////// Calculate body length
            var bodyLength = 0
            // MetaData part
            b.setLength(0)
            b.append("--").append(boundary).append(LINE_FEED)
            b.append(CONTENT_TYPE_PARAM).append("application/json; charset=UTF-8")
                .append(LINE_FEED)
            b.append(LINE_FEED)
            b.append(metadata).append(LINE_FEED)
            b.append(LINE_FEED)
            b.append("--").append(boundary).append(LINE_FEED)
            b.append(CONTENT_TYPE_PARAM).append("text/csv").append(LINE_FEED)
            b.append(LINE_FEED)
            val beforeFilePart = b.toString().toByteArray(charset("UTF_8"))
            bodyLength += beforeFilePart.size

            bodyLength += data.size // File

            b.setLength(0)
            b.append(LINE_FEED)
            b.append("--").append(boundary).append("--")
            val afterFilePart = b.toString().toByteArray(charset("UTF_8"))
            bodyLength += afterFilePart.size

            conn.setRequestProperty("Content-Length", bodyLength.toString())
            //if (BuildConfig.DEBUG_MODE) DebugHelper.log("LENGTH", bodyLength)

            /////// Write to socket
            os = conn.outputStream

            try {
                os!!.write(beforeFilePart)
                os!!.write(data)
                os!!.write(afterFilePart)
                os!!.flush()
            } catch (e: Exception) {
                e.printStackTrace()
            }


            val msg = conn.responseMessage
            val code = conn.responseCode


            if (code == 200) {
                Log.i("writeDbToDrive", "Exported Successfully: $code $msg")

            } else {
                Log.i("writeDbToDrive", "Error: $code $msg")

            }
        } catch (e: Exception) {
            e.printStackTrace()
            Log.i("writeDbToDrive", e.message!!)
        } finally {
            if (os != null) {
                try {
                    os!!.close()
                } catch (e: IOException) {
                }

            }
            conn?.disconnect()
        }
    }

    @Throws(IOException::class)
    private fun readFile(file: File): ByteArray {
        val f = RandomAccessFile(file, "r")
        try {
            val longlength = f.length()
            val length = longlength.toInt()
            if (length.toLong() != longlength)
                throw IOException("File size >= 10 Mb")

            val data = ByteArray(length)
            f.readFully(data)
            return data
        } finally {
            f.close()
        }
    }

    private fun requestAccessToken(mGoogleSignInAccount: GoogleSignInAccount): String? {

        val scope = "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile"



        doAsync {
            try {
                mAccessToken = GoogleAuthUtil.getToken(this@SettingsActivity, mGoogleSignInAccount?.account, scope)
            } catch (e: Exception) {
                Log.i("Error AccessToken", "${e.message}")

                e.printStackTrace()
            }

            uiThread {
                Log.i("AccessTokenMy", "$mAccessToken")
            }

        }

        return mAccessToken
    }

【问题讨论】:

    标签: android android-studio google-drive-api google-drive-android-api


    【解决方案1】:

    在阅读了这个Files: create 文档后,我终于解决了这个问题。我不知道保存在我的应用程序创建的AppData 文件夹中的文件。 AppData 文件夹是隐藏的,只能通过我的应用程序访问。为了能够将文件保存到My Drive 文件夹,我删除了部分元数据

              ` .append(',') 
                .append("\"parents\":").append("[\"").append(APP_FOLDER_ID).append("\"]")`
    

    所以元数据部分现在是这样的

     val b = StringBuilder()
            b.append('{')
                .append("\"name\":\"").append(exportedFileName).append('\"')
                .append(',')
                .append("\"mimeType\":").append("\"text\\/csv\"")
                .append('}')
            val metadata = b.toString()
    

    其他一切都保持不变

    【讨论】:

    • 嗨@RashEngine,我正在做几乎相同的事情,它适用于我的网络,但不适用于移动设备。请检查此expo snack 了解一下在移动设备上,我得到一个 200 和文件 ID,但我看不到上传的文件
    猜你喜欢
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多