【问题标题】:How do I automatically upload the image I took to a cloud storage like Google Drive or Dropbox如何自动将拍摄的图像上传到 Google Drive 或 Dropbox 等云存储
【发布时间】:2014-08-12 12:09:23
【问题描述】:

我是 Android 编程的新手,我想知道是否可以将使用我开发的相机应用程序拍摄的图像自动上传到云存储,如 Google Drive 或 Dropbox。我目前能够将图像保存到内部 SD 卡中。到目前为止,这是我所拥有的:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera_main);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    getWindow().setFormat(PixelFormat.UNKNOWN);
    surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    controlInflater = LayoutInflater.from(getBaseContext());
    View viewControl = controlInflater.inflate(R.layout.camera_control, null);
    LayoutParams layoutParamsControl 
        = new LayoutParams(LayoutParams.FILL_PARENT, 
        LayoutParams.FILL_PARENT);
    this.addContentView(viewControl, layoutParamsControl);

    Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
    buttonTakePicture.setOnClickListener(new Button.OnClickListener(){


        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            camera.takePicture(myShutterCallback, 
                    myPictureCallback_RAW, myPictureCallback_JPG);
        }});

}

ShutterCallback myShutterCallback = new ShutterCallback(){

    @Override
    public void onShutter() {
        // TODO Auto-generated method stub

    }};

PictureCallback myPictureCallback_RAW = new PictureCallback(){

    @Override
    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub

    }};

PictureCallback myPictureCallback_JPG = new PictureCallback(){

    @Override
    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub
        /*Bitmap bitmapPicture 
            = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);  */

        /*Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());

        /*OutputStream imageFileOS;*/


        FileOutputStream outStream = null;

        try 
        {
            /*imageFileOS = getContentResolver().openOutputStream(uriTarget);
            imageFileOS.write(arg0);
            imageFileOS.flush();
            imageFileOS.close();

            Toast.makeText(VuzixCamera.this, "Image saved: " + uriTarget.toString(), Toast.LENGTH_LONG).show();*/

            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "nypdImages");

            if (!mediaStorageDir.exists()) 
            {
                if (!mediaStorageDir.mkdirs()) 
                {
                    Log.d("nypdImages", "Oops! Failed create " + "nypdImages" + " directory");
                }
            }

            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
            String path = mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg";


            outStream = new FileOutputStream(String.format(path, System.currentTimeMillis()));
            outStream.write(arg0);
            outStream.close();

            sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 

        } 
        catch (FileNotFoundException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (IOException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally 
        {
            Toast.makeText(getApplicationContext(), "Image Saved", Toast.LENGTH_SHORT).show();
            //VuzixCamera.super.onBackPressed();
        }

        camera.startPreview();
    }};



@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    // TODO Auto-generated method stub
    if(previewing){
        camera.stopPreview();
        previewing = false;
    }

    if (camera != null){
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            previewing = true;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    camera = Camera.open();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    camera.stopPreview();
    camera.release();
    camera = null;
    previewing = false;
}

【问题讨论】:

    标签: android android-camera dropbox-api android-file google-drive-api


    【解决方案1】:

    这个问题有点开放式,但是可以。我只能与 Dropbox 通话,但您可以使用 Dropbox Core 或 Sync API 将本地文件(例如此类照片)上传到 Dropbox 帐户。

    每个链接页面都有下载相关 SDK 的链接,以及向您展示如何上传和下载文件的教程。

    【讨论】:

      【解决方案2】:

      如果您在 SD 卡上有文件(或只有一个 InputStream),您就成功了。

      我不能为 Dropbox 做担保,但这里有一个连接到 Google Drive 并上传所拍照片的示例。一切都在一个地方,无需使用任何辅助方法。

      注意:您仍然需要执行 Google Drive 的integration 教程。

      package net.twisterrob.example;
      
      import java.io.*;
      
      import android.app.Activity;
      import android.content.*;
      import android.content.IntentSender.SendIntentException;
      import android.net.Uri;
      import android.os.*;
      import android.provider.MediaStore;
      import android.util.Log;
      import android.widget.Toast;
      
      import com.google.android.gms.common.*;
      import com.google.android.gms.common.api.*;
      import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
      import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
      import com.google.android.gms.drive.*;
      import com.google.android.gms.drive.DriveApi.ContentsResult;
      import com.google.android.gms.drive.DriveFolder.DriveFileResult;
      
      /**
       * Upload a single picture taken with the Camera based on some tutorials on Google Drive API:
       * <ul>
       * <li><a href="http://developer.android.com/training/camera/photobasics.html">take a picture</a>
       * <li><a href="https://developers.google.com/drive/android/auth">for connect to work</a>
       * <li><a href="https://developers.google.com/drive/android/create-file">create the file</a>
       * <li><a href="https://developers.google.com/drive/android/files">upload the file</a>
       * </ul>
       * 
       * Permissions needed:
       * <ul>
       * <li><code>&lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /></code>
       * <li><code>&lt;uses-permission android:name="android.permission.CAMERA" /></code>
       * <li><code>&lt;uses-feature android:name="android.hardware.camera" android:required="true"/></code>
       * </ul>
       * 
       * One thing to note with this: for the first connect (sign in/authorization) you need network,
       * but after that everything works without network. 
       */
      public class GoogleDriveUpload extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
          private static final String TAG = "Drive";
      
          private static final int RESOLVE_CONNECTION_REQUEST_CODE = RESULT_FIRST_USER + 0;
          private static final int TAKE_PICTURE_REQUEST_CODE = RESULT_FIRST_USER + 1;
      
          private GoogleApiClient mClient;
          private File requestedFile;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
      
              // TODO init UI
      
              mClient = new GoogleApiClient.Builder(getApplicationContext()) //
                      .addApi(Drive.API) //
                      .addScope(Drive.SCOPE_FILE) //
                      .addConnectionCallbacks(this) //
                      .addOnConnectionFailedListener(this) //
                      .build();
          }
      
          protected void takePicture() {
              Log.v(TAG, "takePicture");
              requestedFile = new File(getExternalCacheDir(), "temp.jpg");
              Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
              takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(requestedFile));
              if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                  startActivityForResult(takePictureIntent, TAKE_PICTURE_REQUEST_CODE);
              }
          }
      
          protected void upload(final File file) {
              Log.v(TAG, "uploading " + file);
              new FileUploader(mClient) {
                  @Override
                  protected void onPostExecute(DriveFile result) {
                      super.onPostExecute(result);
                      if (result != null) {
                          Log.v(TAG, file + " to " + result.getDriveId());
                          Toast.makeText(getApplicationContext(), "Uploaded to Google Drive", Toast.LENGTH_LONG).show();
                          file.delete();
                      } else {
                          Toast.makeText(getApplicationContext(), "Upload failed", Toast.LENGTH_LONG).show();
                      }
                      finish(); // TODO notify user
                  }
              }.execute(file);
          }
      
          @Override
          protected void onStart() {
              super.onStart();
              Log.v(TAG, "onStart: connecting");
              mClient.connect(); // if it's in onStart the whole activity will be connected
          }
      
          @Override
          protected void onStop() {
              Log.v(TAG, "onStop: disconnecting");
              mClient.disconnect();
              super.onStop();
          }
      
          @Override
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {
              switch (requestCode) {
                  case RESOLVE_CONNECTION_REQUEST_CODE:
                      if (resultCode == Activity.RESULT_OK) {
                          Log.v(TAG, "onActivityResult: everything ok, connecting");
                          mClient.connect(); // try again with resolved problem
                          return;
                      } else {
                          Log.v(TAG, "onActivityResult: user cancelled?");
                      }
                      break;
                  case TAKE_PICTURE_REQUEST_CODE:
                      if (resultCode == Activity.RESULT_OK) {
                          Log.v(TAG, "onActivityResult: got an image");
                          upload(requestedFile);
                          return;
                      } else {
                          Log.v(TAG, "onActivityResult: error taking picture");
                      }
                      break;
                  default:
                      // let super do its thing
                      break;
              }
      
              super.onActivityResult(requestCode, resultCode, data);
          }
      
          public void onConnectionFailed(ConnectionResult result) {
              if (!result.hasResolution()) {
                  Log.v(TAG, "onConnectionFailed: cannot resolve: " + result);
                  GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
                  return;
              }
              try {
                  Log.v(TAG, "onConnectionFailed: resolving: " + result);
                  result.startResolutionForResult(this, RESOLVE_CONNECTION_REQUEST_CODE);
              } catch (SendIntentException e) {
                  Log.e(TAG, "Exception while trying to resolve " + result, e);
              }
          }
      
          public void onConnected(Bundle connectionHint) {
              Log.v(TAG, "onConnected: yaay, from here on we can use the Drive API");
              if (requestedFile == null) {
                  takePicture(); // TODO call takePicture() from an onClick button event handler
              }
          }
      
          public void onConnectionSuspended(int reason) {
              Log.v(TAG, "onConnectionSuspended: don't touch Drive API any more");
          }
      
          private static class FileUploader extends AsyncTask<File, Void, DriveFile> {
              private final GoogleApiClient client;
              private FileUploader(GoogleApiClient client) {
                  this.client = client;
              }
      
              @Override
              protected DriveFile doInBackground(File... params) {
                  File file = params[0];
                  ContentsResult result = Drive.DriveApi.newContents(client).await();
                  if (!result.getStatus().isSuccess()) {
                      Log.e(TAG, "Cannot create contents");
                      return null;
                  }
      
                  Contents contents = result.getContents();
                  try {
                      copy(file, contents);
                  } catch (IOException ex) {
                      Log.e(TAG, "Cannot upload file", ex);
                      return null;
                  }
                  MetadataChangeSet metadata = new MetadataChangeSet.Builder() //
                          .setTitle("picture.jpg") //
                          .setMimeType("image/jpeg") //
                          .build();
                  DriveFolder root = Drive.DriveApi.getRootFolder(client);
                  DriveFileResult createResult = root.createFile(client, metadata, contents).await();
                  if (!createResult.getStatus().isSuccess()) {
                      Log.e(TAG, "Cannot create file");
                      return null;
                  }
                  return createResult.getDriveFile();
              }
      
              private static void copy(File source, Contents target) throws IOException {
                  InputStream input = null;
                  OutputStream output = null;
                  try {
                      input = new FileInputStream(source);
                      output = target.getOutputStream();
                      byte[] buffer = new byte[16 * 1014];
                      int read = 0;
                      while ((read = input.read(buffer)) > 0) {
                          output.write(buffer, 0, read);
                      }
                  } catch (IOException ex) {
                      throw ex;
                  } finally {
                      if (input != null) {
                          try {
                              input.close();
                          } catch (IOException ex) {
                              Log.e(TAG, "Cannot close input", ex);
                          }
                      }
                      if (output != null) {
                          try {
                              output.close();
                          } catch (IOException ex) {
                              Log.e(TAG, "Cannot close output", ex);
                          }
                      }
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-05-20
        • 1970-01-01
        • 1970-01-01
        • 2016-06-21
        • 1970-01-01
        • 1970-01-01
        • 2019-08-15
        • 2016-06-13
        相关资源
        最近更新 更多