【问题标题】:Google Drive Android API how to upload a audio file to my drive ? How to sync drive files?Google Drive Android API 如何将音频文件上传到我的驱动器?如何同步驱动文件?
【发布时间】:2014-03-12 11:55:55
【问题描述】:

我已经完成了演示,但我尝试使用上传图像的快速入门示例。但我不知道如何上传音频文件,我将在其中提供文件路径或 Intent Picker 来选择文件。我正在使用 createFile() 方法

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

    • 我需要将其转换为任何流吗?
      • 为什么 google 仅仅为了上传文件就让这件事变得如此复杂?
  2. 如何同步云端硬盘文件?

  3. 如何流式传输(从驱动器播放音频文件)?

下面的代码只是上传什么都不包含的文件。

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");
}

}

【问题讨论】:

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


    【解决方案1】:

    试试这个:

    **
     * 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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      我没有玩过音频文件,但一般来说,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 功能。 不要尝试在工作中以这种方式编写代码,但它可能会让你被解雇 :-)

      祝你好运。

      【讨论】:

      • 您的两个链接都不起作用。可以更新吗?
      【解决方案3】:

      在您的 onConnected 方法中,您创建了新文件,但您从未在其中放入任何新内容。您在此行中创建新内容:

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

      比你在这一行得到它的输出流:

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

      然后在这一行中创建一个空字节数组输出流:

      ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
      

      但是你永远不会用任何内容填充这个“位图流”,最糟糕的是:你永远不会将它写入内容的“输出流”。

      接下来您应该将音频文件的内容写入“bitmapStream”,如下所示:

      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);
      }
      

      现在您的文件内容将包含在“bitmapStrea”中,您可以将其写入新内容的“outputStream”,如下所示:

      outputStream.write(bitmapStream.toByteArray());
      

      比你做'MetadataChangeSet'的东西,你应该没问题。

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

      1. 如果您使用 ByteArrayOutputStream 实例上传音频文件,请不要将其称为“bitmapStream”。

      这是一个使用 AsyncTask 上传图像的类的示例(猜猜我称之为 ByteArrayOutputStream... 对 - 'bitmapStream'):

      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 services 类。

      【讨论】:

        【解决方案4】:

        这很简单。经过我的努力,我找到了解决办法。

        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);
                        }
                    });
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-01-22
          • 1970-01-01
          • 1970-01-01
          • 2020-10-10
          • 1970-01-01
          • 1970-01-01
          • 2018-11-10
          • 2018-11-20
          相关资源
          最近更新 更多