Google Drive Android API如何将音频文件上传到我的驱动器?如何同步驱动器文件?

时间:2014-03-12 11:55:55

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

我已经浏览了Demo,但我尝试使用QuickStart示例上传图像。但我没有得到如何上传音频文件,我将在其中提供我的文件路径或Intent Picker来选择文件。我正在使用 createFile()方法

  1. 如何将音频文件上传到我的驱动器?

    • 我需要将它转换为任何流吗?
      • 为什么谷歌只是为了上传文件这么复杂?
  2. 如何同步云端硬盘文件?

  3. 如何播放(播放音频文件)?

  4. 以下代码只上传包含任何内容的文件。

    public class MainActivity extends Activity implements ConnectionCallbacks,
        OnConnectionFailedListener {
    
    private static final String TAG = "android-drive-quickstart";
    //private static final int REQUEST_CODE_CAPTURE_IMAGE = 1;
    private static final int REQUEST_CODE_CREATOR = 2;
    private static final int REQUEST_CODE_RESOLUTION = 3;
    private static final int PICKFILE_RESULT_CODE = 1;
    private static Uri fileUri;
    private ContentsResult result;
    private GoogleApiClient mGoogleApiClient;
    private Bitmap mBitmapToSave;
    
    
    @Override
    protected void onResume() {
        super.onResume();
        if (mGoogleApiClient == null) {
            // Create the API client and bind it to an instance variable.
            // We use this instance as the callback for connection and connection
            // failures.
            // Since no account name is passed, the user is prompted to choose.
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(Drive.API)
                    .addScope(Drive.SCOPE_FILE)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }
        // Connect the client. Once connected, the camera is launched.
        mGoogleApiClient.connect();
    }
    
    
    
    
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // Called whenever the API client fails to connect.
        Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
        if (!result.hasResolution()) {
            // show the localized error dialog.
            showToast("Error in on connection failed");
            GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
            return;
        }
        // The failure has a resolution. Resolve it.
        // Called typically when the app is not yet authorized, and an
        // authorization
        // dialog is displayed to the user.
        try {
            result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
        } catch (SendIntentException e) {
            showToast("error"+e.toString());
            Log.e(TAG, "Exception while starting resolution activity", e);
        }
    }
    
    
    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "API client connected.");
    
        showToast("Inside Connected");
        result = Drive.DriveApi.newContents(mGoogleApiClient).await();
    
        showToast(""+result.getContents().toString());
        OutputStream outputStream = result.getContents().getOutputStream();
        ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
        //java.io.File fileContent = new java.io.File(fileUri.getPath());
    
    
        MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
        .setTitle("New file")
        .setMimeType("audio/MP3")
        .setStarred(true).build();
        showToast("meta data created");
        DriveFileResult dfres= Drive.DriveApi.getRootFolder(getGoogleApiClient())
        .createFile(getGoogleApiClient(), changeSet, result.getContents())
        .await();
        showToast("await() complete");
        if (!result.getStatus().isSuccess()) {
            showToast("Error while trying to create the file");
            return;
        }
        showToast("Created a file: " + dfres.getDriveFile().getDriveId());
    }
    
    
    
    private void saveFileToDrive()
    {
    
    }
    
    
    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (requestCode == REQUEST_CODE_RESOLUTION && resultCode == RESULT_OK) {
            mGoogleApiClient.connect();
            showToast("Connected");
        }
    }
    
    
    
    @Override
    protected void onPause() {
        if (mGoogleApiClient != null) {
            mGoogleApiClient.disconnect();
        }
        super.onPause();
    }
    
    
    public void showToast(final String toast) {
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
            Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();
          }
        });
      }
    
    public GoogleApiClient getGoogleApiClient() {
        return mGoogleApiClient;
      }
    
    @Override
    public void onConnectionSuspended(int cause) {
        Log.i(TAG, "GoogleApiClient connection suspended");
    }
    

    }

4 个答案:

答案 0 :(得分:3)

试试这个:

**
 * An AsyncTask that maintains a connected client.
 */
public abstract class ApiClientAsyncTask<Params, Progress, Result>
        extends AsyncTask<Params, Progress, Result> {

    private GoogleApiClient mClient;

    public ApiClientAsyncTask(Context context) {
        GoogleApiClient.Builder builder = new GoogleApiClient.Builder(context)
                .addApi(Drive.API)
                .addScope(Drive.SCOPE_FILE);
        mClient = builder.build();
    }

    @Override
    protected final Result doInBackground(Params... params) {
        Log.d("TAG", "in background");
        final CountDownLatch latch = new CountDownLatch(1);
        mClient.registerConnectionCallbacks(new ConnectionCallbacks() {
            @Override
            public void onConnectionSuspended(int cause) {
            }

            @Override
            public void onConnected(Bundle arg0) {
                latch.countDown();
            }
        });
        mClient.registerConnectionFailedListener(new OnConnectionFailedListener() {
            @Override
            public void onConnectionFailed(ConnectionResult arg0) {
                latch.countDown();
            }
        });
        mClient.connect();
        try {
            latch.await();
        } catch (InterruptedException e) {
            return null;
        }
        if (!mClient.isConnected()) {
            return null;
        }
        try {
            return doInBackgroundConnected(params);
        } finally {
            mClient.disconnect();
        }
    }

    /**
     * Override this method to perform a computation on a background thread, while the client is
     * connected.
     */
    protected abstract Result doInBackgroundConnected(Params... params);

    /**
     * Gets the GoogleApliClient owned by this async task.
     */
    protected GoogleApiClient getGoogleApiClient() {
        return mClient;
    }
    }

要保存文件的类:

 /**
     * An async task that creates a new text file by creating new contents and
     * metadata entities on user's root folder. A number of blocking tasks are
     * performed serially in a thread. Each time, await() is called on the
     * result which blocks until the request has been completed.
     */
public class CreateFileAsyncTask extends ApiClientAsyncTask<String, Void, Metadata>
{

    public CreateFileAsyncTask(Context context)
    {
        super(context);
    }

    @Override
    protected Metadata doInBackgroundConnected(String... arg0)
    {
        // First we start by creating a new contents, and blocking on the
        // result by calling await().
        DriveApi.ContentsResult contentsResult = Drive.DriveApi.newContents(getGoogleApiClient()).await();

        if (!contentsResult.getStatus().isSuccess()) {
            // We failed, stop the task and return.
            return null;
        }

        //file to save in drive
        String pathFile = arg0[0];
        File file = new File(pathFile);

        // Read the contents and open its output stream for writing, then
        // write a short message.
        Contents originalContents = contentsResult.getContents();
        OutputStream os = originalContents.getOutputStream();

        try
        {
            InputStream dbInputStream = new FileInputStream(file);

            byte[] buffer = new byte[1024];
            int length;
            int counter = 0;
            while((length = dbInputStream.read(buffer)) > 0)
            {
                ++counter;
                os.write(buffer, 0, length);
            }

            dbInputStream.close();
            os.flush();
            os.close();

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        // Create the metadata for the new file including title and MIME
        // type.
        MetadataChangeSet originalMetadata = new MetadataChangeSet.Builder()
        .setTitle(file.getName())
        .setMimeType("application/x-sqlite3").build();

        // Create the file in the root folder, again calling await() to
        // block until the request finishes.
        DriveFolder rootFolder = Drive.DriveApi.getRootFolder(getGoogleApiClient());
        DriveFolder.DriveFileResult fileResult = rootFolder.createFile(
        getGoogleApiClient(), originalMetadata, originalContents).await();

        if (!fileResult.getStatus().isSuccess()) {
            // We failed, stop the task and return.
            return null;
        }

        // Finally, fetch the metadata for the newly created file, again
        // calling await to block until the request finishes.
        DriveResource.MetadataResult metadataResult = fileResult.getDriveFile()
        .getMetadata(getGoogleApiClient())
        .await();

        if (!metadataResult.getStatus().isSuccess()) {
            // We failed, stop the task and return.
            return null;
        }
        // We succeeded, return the newly created metadata.
        return metadataResult.getMetadata();
    }

    @Override
    protected void onPostExecute(Metadata result)
    {
        super.onPostExecute(result);

        if (result == null)
        {
            // The creation failed somehow, so show a message.
            App.showAppMsg(getActivity(),"Error while creating the file.",Style.ALERT);
            return;
        }
        // The creation succeeded, show a message.
        App.showAppMsg(getActivity(),"File created: " + result.getDriveId(),Style.CONFIRM);
    }
}

答案 1 :(得分:1)

我没有玩过音频文件,但一般情况下,Google Drive Android API(GDAA)并不处理音频文件。您只需创建一个文件,设置元数据并填充二进制内容。查看code here(加上一些readme blah blah here)。你会找到一个代码行

 byte[] buff = ("written on: " + _dfn.getName()).getBytes();
 if (null == _gc.creatFile(fldr, name, MIMETEXT, buff))  return;

那里产生 byte [] 缓冲区并创建一个文本MIME类型的文件。因此,尝试使用它,只需替换MIME类型并将“buff”填充到音频流中。我用JPEG二进制文件成功完成了。

还有 GooApiClnt 包装类可以处理大多数基本的GDAA功能。 不要尝试以这种方式在工作中编码,但是,它可能会让你解雇: - )

祝你好运。

答案 2 :(得分:1)

在onConnected方法中,您可以创建新文件,但不会在其中添加任何新内容。您可以在此行中创建新内容:

result = Drive.DriveApi.newContents(mGoogleApiClient).await();

比你在这一行中掌握它的输出流:

OutputStream outputStream = result.getContents().getOutputStream();

并且在此行中创建一个空字节数组输出流:

ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();

但你永远不会填补这个位图流#39;任何内容,最糟糕的是:你永远不会把它写到你的内容&#39; outputStream&#39;。

接下来应该做的是将音频文件的内容写入&#39; bitmapStream&#39;像这样的东西:

InputStream in = file.getInputStream(/*you need to get the file's path and put it here*/ "some_audio_file.mp3");
int singleByte;
while((singleByte = in.read()) != -1){
   bitmapStream.write(b);
}

现在,您已将文件的内容置于&bitfaStrea&#39;你可以把它写到新内容的输出流#39;像这样:

outputStream.write(bitmapStream.toByteArray());

比你做的MetadataChangeSet&#39;什么东西,你应该没事。

一些建议:  1.在主线程上执行文件或网络活动(或您的案例中的文件和网络活动)等I / O操作不是一个好习惯。最好使用AsyncTask在后台线程中执行它。

  1. 不要调用您的ByteArrayOutputStream实例&#39; bitmapStream&#39;如果您使用它来上传音频文件。
  2. 这是一个使用AsyncTask上传图像的类的示例(并猜测我称之为ByteArrayOutputStream ...右 - &#39; bitmapStream&#39;):

    public class TakePhotoActivity extends Activity implements
            GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener {
    
        /**
         * Request code for auto Google Play Services error resolution.
         */
        protected static final int REQUEST_CODE_RESOLUTION = 1;
        private static final String TAG = "TakePhotoActivity";
        private static final String KEY_IN_RESOLUTION = "is_in_resolution";
        private static final int REQUEST_CODE_CREATOR = 2;
    
        /**
         * Google API client.
         */
        private GoogleApiClient mGoogleApiClient;
    
        /**
         * Receives the new file's contents and executes the editor AsyncTask
         */
        private ResultCallback<DriveApi.ContentsResult> mSaveFileCallback = new ResultCallback<DriveApi.ContentsResult>() {
            @Override
            public void onResult(DriveApi.ContentsResult contentsResult) {
                EditFileAsyncTask editFileAsyncTask = new EditFileAsyncTask();
                editFileAsyncTask.execute(contentsResult);
            }
        };
    
        /**
         * Determines if the client is in a resolution state, and
         * waiting for resolution intent to return.
         */
        private boolean mIsInResolution;
    
        private Bitmap mBitmapToSave;
    
        /**
         * Called when the activity is starting. Restores the activity state.
         */
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_take_menu_photo);
    
            if (savedInstanceState != null) {
                mIsInResolution = savedInstanceState.getBoolean(KEY_IN_RESOLUTION, false);
            }
    
            try {
                InputStream inputStream = getAssets().open("some_image.jpg");
                mBitmapToSave = BitmapFactory.decodeStream(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * Called when the Activity is made visible.
         * A connection to Play Services need to be initiated as
         * soon as the activity is visible. Registers {@code ConnectionCallbacks}
         * and {@code OnConnectionFailedListener} on the
         * activities itself.
         */
        @Override
        protected void onStart() {
            super.onStart();
            if (mGoogleApiClient == null) {
                mGoogleApiClient = new GoogleApiClient.Builder(this)
                        .addApi(Drive.API)
                        .addScope(Drive.SCOPE_FILE)
                                // Optionally, add additional APIs and scopes if required.
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .build();
            }
            Log.d("test", "connect()");
            mGoogleApiClient.connect();
        }
    
        /**
         * Called when activity gets invisible. Connection to Play Services needs to
         * be disconnected as soon as an activity is invisible.
         */
        @Override
        protected void onStop() {
            if (mGoogleApiClient != null) {
                mGoogleApiClient.disconnect();
            }
            super.onStop();
        }
    
        /**
         * Saves the resolution state.
         */
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putBoolean(KEY_IN_RESOLUTION, mIsInResolution);
        }
    
        /**
         * Handles Google Play Services resolution callbacks.
         */
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            switch (requestCode) {
                case REQUEST_CODE_RESOLUTION:
                    retryConnecting();
                    break;
            }
        }
    
        private void retryConnecting() {
            mIsInResolution = false;
            if (!mGoogleApiClient.isConnecting()) {
                Log.d("test", "connect()");
                mGoogleApiClient.connect();
            }
        }
    
        /**
         * Called when {@code mGoogleApiClient} is connected.
         */
        @Override
        public void onConnected(Bundle connectionHint) {
            Log.i(TAG, "GoogleApiClient connected");
            // TODO: Start making API requests.
            if (mBitmapToSave != null) {
                saveFileToDrive();
            }
        }
    
        /**
         * Called when {@code mGoogleApiClient} connection is suspended.
         */
        @Override
        public void onConnectionSuspended(int cause) {
            Log.i(TAG, "GoogleApiClient connection suspended");
            retryConnecting();
        }
    
        /**
         * Called when {@code mGoogleApiClient} is trying to connect but failed.
         * Handle {@code result.getResolution()} if there is a resolution
         * available.
         */
        @Override
        public void onConnectionFailed(ConnectionResult result) {
            Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
            if (!result.hasResolution()) {
                // Show a localized error dialog.
                GooglePlayServicesUtil.getErrorDialog(
                        result.getErrorCode(), this, 0, new OnCancelListener() {
                            @Override
                            public void onCancel(DialogInterface dialog) {
                                retryConnecting();
                            }
                        }
                ).show();
                return;
            }
            // If there is an existing resolution error being displayed or a resolution
            // activity has started before, do nothing and wait for resolution
            // progress to be completed.
            if (mIsInResolution) {
                return;
            }
            mIsInResolution = true;
            try {
                result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
            } catch (SendIntentException e) {
                Log.e(TAG, "Exception while starting resolution activity", e);
                retryConnecting();
            }
        }
    
        private void saveFileToDrive() {
            Log.i(TAG, "Creating new contents.");
            Drive.DriveApi.newContents(mGoogleApiClient).setResultCallback(mSaveFileCallback);
        }
    
        private void showMessage(String message) {
            Log.i(TAG, message);
    //        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
        }
    
        private class EditFileAsyncTask extends AsyncTask<DriveApi.ContentsResult, Void, Boolean> {
    
            @Override
            protected Boolean doInBackground(DriveApi.ContentsResult... params) {
                DriveApi.ContentsResult contentsResult = params[0];
                if (!contentsResult.getStatus().isSuccess()) {
                    showMessage("Failed to create new contents.");
                    return false;
                }
                showMessage("New contents created.");
                OutputStream outputStream = contentsResult.getContents().getOutputStream();
                ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
                mBitmapToSave.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
                try {
                    outputStream.write(bitmapStream.toByteArray());
                } catch (IOException e) {
                    showMessage("Unable to write file contents.");
                    e.printStackTrace();
                }
    
                MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
                        .setMimeType("image/jpeg")
                        .setTitle("some_image.jpg")
                        .build();
    
                IntentSender intentSender = Drive.DriveApi
                        .newCreateFileActivityBuilder()
                        .setInitialMetadata(metadataChangeSet)
                        .setInitialContents(contentsResult.getContents())
                        .build(mGoogleApiClient);
    
                try {
                    startIntentSenderForResult(intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
                } catch (SendIntentException e) {
                    showMessage("Failed to launch file chooser.");
                    e.printStackTrace();
                }
                return true;
            }
    
            @Override
            protected void onPostExecute(Boolean result) {
                if (!result) {
                    showMessage("Error while editing contents");
                    return;
                }
                showMessage("Successfully edited contents");
            }
        }
    }
    
    • 顺便说一下,这个类中的大部分代码都是由Android Studio自动生成的,因为当我创建项目时,我将初始类标记为google服务类。

答案 3 :(得分:1)

很简单。在我努力之后,我找到了解决方案。

private String mFileName = null;
File folder = new File(Environment.getExternalStorageDirectory() + 
"/FolderFile");
    if (!folder.exists()) {
        folder.mkdir();
    }
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
    mFileName += "/FolderFile/a.mp3";

录制音频后。你必须 buildGoogleSignInClient()

createFileWithIntent(mFileName);

private void createFileWithIntent(String I) {
     final String audio = I;
    final Task<DriveFolder> rootFolderTask = getDriveResourceClient().getRootFolder();
    final Task<DriveContents> createContentsTask = getDriveResourceClient().createContents();
    Tasks.whenAll(rootFolderTask, createContentsTask)
            .continueWithTask(new Continuation<Void, Task<DriveFile>>() {
                @RequiresApi(api = Build.VERSION_CODES.KITKAT)
                public Task<DriveFile> then(@NonNull Task<Void> task) throws Exception {
                    DriveFolder PASTA = rootFolderTask.getResult();
                    DriveContents DADOS = createContentsTask.getResult();

                    File file = new File(audio);
                    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 = DADOS.getOutputStream();
                    outputStream.write(baos.toByteArray());

                    MetadataChangeSet TIPO = new MetadataChangeSet.Builder()
                            .setMimeType("audio/mp3")
                            .setTitle("audio.mp3")
                            .setStarred(true)
                            .build();


                    return getDriveResourceClient().createFile(PASTA, TIPO, DADOS);
                }
            });

}