简体   繁体   中英

Google Drive Android API how to upload a audio file to my drive ? How to sync drive files?

I have gone through Demo's but I tried with the QuickStart example in which a image is uploaded. but I am not getting how to upload a audio file in which i will give path to my files or Intent Picker to select the file.I am using createFile() method

  1. how to upload a audio file to my drive?

    • I need to convert it to any streams ?
      • why google has made this so much complicated just to upload file?
  2. How to Synch Drive files ?

  3. How to stream (play audio file from drive)?

The Below code just upload file which contains nothing.

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

}

Try this:

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

Class to save file:

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

I haven't played with audio files, but in general, the Google Drive Android API (GDAA) does not deal with audio files per say. You just create a file, set metadata and stuff binary content in it. Look at the code here (plus some readme blah blah here ). You'll find a code line

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

there, that produces byte[] buffer and creates a file with text MIME type. So, try to use it, just replace the MIME type and stuff the 'buff' with your audio stream. I do it successfully with JPEG binaries.

There is also GooApiClnt wrapper class there that handles most of the basic GDAA functions. Don't try to code this way at work, though, it may get you fired :-) .

Good luck.

In your onConnected method you create the new file, but you never put any new content in it. You create the new content in this line:

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

Than you get a hold of it's output stream in this line:

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

And than you create an empty byte array output stream in this line:

ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();

But you never fill this 'bitmapStream' with any content, and worst: you never write it to your content's 'outputStream'.

What you should do next is write your audio file's contents to 'bitmapStream' something like this:

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

Now you'd have your file's content inside 'bitmapStrea' and you can write it to the new content's 'outputStream' like this:

outputStream.write(bitmapStream.toByteArray());

Than you do the 'MetadataChangeSet' stuff and you should be fine.

Some advices: 1. It is not a good practice to do I/O operations like file or network activities (or file AND network activities in your case) on the main thread. Better use an AsyncTask to do it in a background thread.

  1. Don't call your ByteArrayOutputStream instance 'bitmapStream' if you use it to upload an audio file.

Here's an example of a class that uses an AsyncTask to upload an image (and guess what I called the ByteArrayOutputStream... right - '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");
        }
    }
}
  • By the way, most of the code in this class was auto-generated by Android Studio, because when I created the project I marked the initial class to be a google services class.

It,s simple. After I trying hard, I found the solution.

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

After the audio is recorded. You must 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);
                }
            });

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM