【问题标题】:Uploading video to Google Drive programmatically (Android API)以编程方式将视频上传到 Google Drive (Android API)
【发布时间】:2014-12-09 14:00:40
【问题描述】:

我已遵循 Drive API 指南 (https://developer.android.com/google/play-services/drive.html),我的应用现在可以顺利上传照片,但我现在尝试上传视频 (mp4),但没有成功。

有谁知道如何做到这一点?该视频是一个新生成的 mp4 文件,我知道它在设备上的存储路径。

图片是这样处理的:

Drive.DriveApi.newDriveContents(mDriveClient).setResultCallback(
    new ResultCallback<DriveContentsResult>() {

@Override
public void onResult(DriveContentsResult result) {
    if (!result.getStatus().isSuccess()) {
        Log.i(TAG, "Failed to create new contents.");
        return;
    }
    OutputStream outputStream = result.getDriveContents().getOutputStream();
    // Write the bitmap data from it.
    ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 80, bitmapStream);
    try {
        outputStream.write(bitmapStream.toByteArray());
    } catch (IOException e1) {
        Log.i(TAG, "Unable to write file contents.");
    }
    image.recycle();
    outputStream = null;
    String title = Shared.getOutputMediaFile(Shared.MEDIA_TYPE_IMAGE).getName();
    MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
        .setMimeType("image/jpeg").setTitle(title)
        .build();
    Log.i(TAG, "Creating new pic on Drive (" + title + ")");

    Drive.DriveApi.getFolder(mDriveClient,
        mPicFolderDriveId).createFile(mDriveClient,
        metadataChangeSet, result.getDriveContents());
        }
    });
}

我感兴趣的是文件的替代品,在这种情况下指向“video/mp4”。

【问题讨论】:

  • 如何将 csv 文件上传到 gdrive,就像您对图像/视频所做的那样
  • 如果您上传像 2 GB 这样的大视频,此代码将崩溃...您在 ByteArrayOutputStream 中写入整个文件...不好

标签: android google-drive-android-api


【解决方案1】:

不多说,只提几点建议:

您要上传的任何内容(图片、文本、视频...)都来自

  1. 创建文件
  2. 设置元数据(标题、MIME 类型、描述...)
  3. 设置内容(字节流)

您提到的演示使用图像(JPEG 字节流)进行,您需要使用视频进行。因此,您需要实施的更改是:

  • 将“image/jpeg”MIME 类型替换为您需要的类型 视频
  • 复制您的视频流 (outputStream.write(bitmapStream.toByteArray())...)

到内容。

这些是您需要进行的唯一更改。 Google Drive Android API 并不关心您的内容和元数据是什么,它只是将其抓取并推送到 Google Drive。

在 Google 云端硬盘中,应用程序(网络、Android 等)读取元数据和内容,并进行相应处理。

【讨论】:

  • 我正在尝试在用户使用他的帐户登录后上传 csv 文件,但我无法使用服务上传这是有什么方法可以在这里上传我的问题stackoverflow.com/questions/27738070/…
  • 我实际上已经阅读了你关于 SO 的问题,但不幸的是我现在太忙了。你可以尝试下载这个测试,我很久以前就一起打过 - 所以它可能已经过时了。 github.com/seanpjanson/140201-GDAA。它写入虚拟文本并在驱动器上创建文件。由于 CSV 文件是文本文件,因此您可能会成功使用它(但要修改 MIME 类型)。我希望在 2 周内发布一个新版本。
【解决方案2】:

这是我实现上传视频的完整代码。 步骤:

  • 从 uri 获取视频文件(在我的例子中)。
  • 从代码中提到的字节数组输出流中获取字节数组
  • 将字节数组写入输出流
  • api会在后台上传文件

公共类 UploadVideo 扩展 AppCompatActivity {

DriveClient mDriveClient;
DriveResourceClient mDriveResourceClient;
GoogleSignInAccount googleSignInAccount;
String TAG = "Drive";
private final int REQUEST_CODE_CREATOR = 2013;
Task<DriveContents> createContentsTask;
String uri;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_upload_video);
    //Fetching uri or path from previous activity.
    uri = getIntent().getStringExtra("uriVideo");
    //Get previously signed in account.
    googleSignInAccount = GoogleSignIn.getLastSignedInAccount(this);
    if (googleSignInAccount != null) {
        mDriveClient = Drive.getDriveClient(getApplicationContext(), googleSignInAccount);
        mDriveResourceClient =
                Drive.getDriveResourceClient(getApplicationContext(), googleSignInAccount);
    }
    else Toast.makeText(this, "Login again and retry", Toast.LENGTH_SHORT).show();
    createContentsTask = mDriveResourceClient.createContents();
    findViewById(R.id.uploadVideo).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
                createFile();
        }
    });
}

private void createFile() {
    // [START create_file]
    final Task<DriveFolder> rootFolderTask = mDriveResourceClient.getRootFolder();
    final Task<DriveContents> createContentsTask = mDriveResourceClient.createContents();
    Tasks.whenAll(rootFolderTask, createContentsTask)
            .continueWithTask(new Continuation<Void, Task<DriveFile>>() {
                @Override
                public Task<DriveFile> then(@NonNull Task<Void> task) throws Exception {
                    DriveFolder parent = rootFolderTask.getResult();
                    DriveContents contents = createContentsTask.getResult();
                    File file = new File(uri);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buf = new byte[1024];
                    FileInputStream fis = new FileInputStream(file);
                    for (int readNum; (readNum = fis.read(buf)) != -1;) {
                        baos.write(buf, 0, readNum);
                    }
                    OutputStream outputStream = contents.getOutputStream();
                    outputStream.write(baos.toByteArray());

                    MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                            .setTitle("MyVideo.mp4") // Provide you video name here
                            .setMimeType("video/mp4") // Provide you video type here
                            .build();

                    return mDriveResourceClient.createFile(parent, changeSet, contents);
                }
            })
            .addOnSuccessListener(this,
                    new OnSuccessListener<DriveFile>() {
                        @Override
                        public void onSuccess(DriveFile driveFile) {
                            Toast.makeText(Upload.this, "Upload Started", Toast.LENGTH_SHORT).show();
                            finish();
                        }
                    })
            .addOnFailureListener(this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.e(TAG, "Unable to create file", e);
                    finish();
                }
            });
    // [END create_file]
}

}

【讨论】:

  • 请解释您的答案,而不是仅仅提供链接。链接可能会随着时间而改变。
【解决方案3】:

如果您想将任何文件上传到 Google Drive,请使用以下代码和同步任务,它会将您的文件上传到 Drive。

AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() 
                {
            @Override
            protected String doInBackground(Void... params) 
            {
               String file_type="video/mp4"; //write your file type
               File body = new File();                   
               File FileRtr = null;
               body.setTitle(myfile.getName());
               body.setMimeType(file_type);
               body.setParents(Arrays.asList(new ParentReference().setId(LocationID))); //LocationID means the path in the drive e where you want to upload it
            try 
            {
              FileContent mediaContent = new FileContent(file_type, myfile);
              FileRtr = mService.files().insert(body, mediaContent).execute();

              if ( FileRtr != null) 
              {
                System.out.println("File uploaded: " +  FileRtr.getTitle());

              }
              }
                catch (IOException e) 
                {
                 System.out.println("An error occurred: " + e.getMessage());
                }
                return null;

            } 
            protected void onPostExecute(String token) 
            {
             Toast.makeText(mContext, "Uploaded Successfuly",Toast.LENGTH_LONG).show();
            } 
            };
        task.execute();     

【讨论】:

  • Pir,您建议使用 RESTful API (developers.google.com/drive/v2/reference),而问题属于 GDAA (developers.google.com/drive/android)。由于 GDAA 中的时间/延迟问题,混合使用这 2 个不是一个好主意。正如我已经多次提到的那样,我设法在删除后数小时内将“GDAA”写入由 RESTful 删除的文件。或者在一个早已不复存在的文件夹中创建一个文件。
【解决方案4】:

OP 的解决方案。

感谢seanpj,原来我高估了这个难度,我现在用这个方法上传图片和视频:

/**
 * Create a new file and save it to Drive.
 */
private void saveFiletoDrive(final File file, final String mime) {
    // Start by creating a new contents, and setting a callback.
    Drive.DriveApi.newDriveContents(mDriveClient).setResultCallback(
            new ResultCallback<DriveContentsResult>() {
                @Override
                public void onResult(DriveContentsResult result) {
                    // If the operation was not successful, we cannot do
                    // anything
                    // and must
                    // fail.
                    if (!result.getStatus().isSuccess()) {
                        Log.i(TAG, "Failed to create new contents.");
                        return;
                    }
                     Log.i(TAG, "Connection successful, creating new contents...");
                    // Otherwise, we can write our data to the new contents.
                    // Get an output stream for the contents.
                    OutputStream outputStream = result.getDriveContents()
                            .getOutputStream();
                    FileInputStream fis;
                    try {
                        fis = new FileInputStream(file.getPath());
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        byte[] buf = new byte[1024];
                        int n;
                        while (-1 != (n = fis.read(buf)))
                            baos.write(buf, 0, n);
                        byte[] photoBytes = baos.toByteArray();
                        outputStream.write(photoBytes);

                        outputStream.close();
                        outputStream = null;
                        fis.close();
                        fis = null;

                    } catch (FileNotFoundException e) {
                        Log.w(TAG, "FileNotFoundException: " + e.getMessage());
                    } catch (IOException e1) {
                        Log.w(TAG, "Unable to write file contents." + e1.getMessage());
                    }

                    String title = file.getName();
                    MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
                            .setMimeType(mime).setTitle(title).build();

                    if (mime.equals(MIME_PHOTO)) {
                        if (VERBOSE)
                            Log.i(TAG, "Creating new photo on Drive (" + title
                                    + ")");
                        Drive.DriveApi.getFolder(mDriveClient,
                                mPicFolderDriveId).createFile(mDriveClient,
                                metadataChangeSet,
                                result.getDriveContents());
                    } else if (mime.equals(MIME_VIDEO)) {
                        Log.i(TAG, "Creating new video on Drive (" + title
                                + ")");
                        Drive.DriveApi.getFolder(mDriveClient,
                                mVidFolderDriveId).createFile(mDriveClient,
                                metadataChangeSet,
                                result.getDriveContents());
                    }

                    if (file.delete()) {
                        if (VERBOSE)
                            Log.d(TAG, "Deleted " + file.getName() + " from sdcard");
                    } else {
                        Log.w(TAG, "Failed to delete " + file.getName() + " from sdcard");
                    }
                }
            });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    相关资源
    最近更新 更多