1

私はデモを行ってきましたが、画像がアップロードされる QuickStart の例を試しました。しかし、ファイルへのパスを指定する音声ファイルをアップロードする方法、またはファイルを選択するためのインテント ピッカーを取得する方法がわかりません。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");
}

}

4

4 に答える 4

1

私は音声ファイルで遊んだことはありませんが、一般に、Google Drive Android API (GDAA) は言うまでもなく音声ファイルを処理しません。ファイルを作成し、メタデータを設定し、その中にバイナリ コンテンツを詰め込むだけです。ここのコードを見てください(さらに、いくつかのreadme 何とかここ)。コード行が見つかります

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

そこで、byte[]バッファを生成し、テキスト MIME タイプのファイルを作成します。MIMEタイプを置き換えて、「バフ」をオーディオストリームに詰め込むだけです。私はJPEGバイナリで成功しています。

基本的な GDAA 関数のほとんどを処理するGooApiClntラッパー クラスもあります。ただし、職場でこの方法でコーディングしようとしないでください。解雇される可能性があります :-) .

幸運を。

于 2014-03-12T18:10:44.800 に答える
1

onConnected メソッドで新しいファイルを作成しますが、その中に新しいコンテンツを入れることはありません。次の行で新しいコンテンツを作成します。

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

この行で出力ストリームを取得するよりも:

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

そして、次の行で空のバイト配列出力ストリームを作成します。

ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();

ただし、この「bitmapStream」にコンテンツを入力することはありません。最悪の場合、コンテンツの「outputStream」に書き込むことはありません。

次にすべきことは、オーディオ ファイルの内容を次のように「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 サービス クラスとしてマークしたためです。
于 2014-05-03T22:52:06.873 に答える