Android - 上传谷歌硬盘上的现有(内部存储器)文件

时间:2014-05-04 19:55:11

标签: android google-drive-api

我花了最后8个小时找到一种方法将文件从我的Android手机的内存上传到谷歌驱动器帐户。 我现在非常沮丧。 GitHub上的官方示例解释了如何拍摄照片并将其上传到驱动器上。我的问题不同了,我的设备上已有文件,我想将其上传到硬盘上。 这是我的最后一次尝试(这是受到网络上发现的各种例子的启发):

公共类MainActivity扩展了ActionBarActivity {

private GoogleAccountCredential credential;
private static Drive service;
int ACCOUNT_REQUEST = 1;




@Override
protected void onCreate(Bundle savedInstanceState)  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
    startActivityForResult(credential.newChooseAccountIntent(), ACCOUNT_REQUEST);

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
        String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
        if (accountName != null) {
            credential.setSelectedAccountName(accountName);
            Drive.Builder builder = new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential);
            builder.setApplicationName("Test Application");
            service =builder.build();
            uploadTheFile();
        }
    }


}

public void uploadTheFile() {
    String filePath = "storage/sdcard0/file.txt";
    String fileName = "File";
    File body = new File();
    body.setTitle(fileName);
    body.setDescription(fileName);
    body.setMimeType("text/plain");

    java.io.File fileContent = new java.io.File(filePath);
    FileContent mediaContent = new FileContent("text/plain", fileContent);

    try {
        File file = service.files().insert(body, mediaContent).execute();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我可以选择上传文件的帐户(file.txt),但随后会崩溃:

  

java.lang.IllegalStateException:从主线程调用它会导致死锁

我试图提供尽可能多的信息,如果您需要更多信息,请不要退出询问!谢谢!

编辑:感谢greenapps解决了死锁问题,但我仍然无法上传我的文件:我应该把我的客户端ID和客户端秘密放在哪里?谢谢!

3 个答案:

答案 0 :(得分:1)

   String filePath = "storage/sdcard0/file.txt";

将其更改为

   String filePath = "/storage/sdcard0/file.txt";

在上传之前检查该文件是否存在。

   File file = new File (filePath);

   if ( ! file.exists ) )
       {
        message that file does not exist

        return false;
       }

您可以通过将uploadFile()放入AsyncTask来解决您的IllegalStateException

答案 1 :(得分:0)

如果你可以上传照片"快速入门"示范代码工作(本身不是一个小任务),尝试修改该代码以将您的文件(而不是照片)复制到Drive的outputStream,如下面的代码所示,这对我有用。 (我不是一个认真的Java程序员,所以如果有更好的方法将文件复制到outputStream,我不会感到惊讶。)

        public void onResult(ContentsResult result) {
            // Get an output stream for the contents.
            OutputStream outputStream = result.getContents().getOutputStream();

            // Write specified local file to Google Drive output stream.
            byte[] buf = new byte[1024];
            int nbyteWritten = 0;
            int nbyte;
            try {
                DataInputStream dis = new DataInputStream(new FileInputStream(file));
                DataOutputStream dos = new DataOutputStream(outputStream);
                while ((nbyte = dis.read(buf)) > 0) {
                    dos.write(buf, 0, nbyte);
                    nbyteWritten += nbyte;
                }
                dis.close();
                dos.close();
            } catch (IOException e) {
                Log.i(TAG, "Unable to write file contents.");
            }

答案 2 :(得分:0)

使用Android专用API可以轻松实现这一目标。见create files。它为您处理所有授权和上传。只需将磁盘上本地文件中的内容复制到新内容对象提供的OutputStream中即可。