Как автоматически загрузить загруженное изображение в облачное хранилище, такое как Google Drive или Dropbox?
Я новичок в программировании на 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;
}
2 ответа
Вопрос немного открытый, но да. Я могу говорить только с Dropbox, но вы можете использовать Dropbox Core или Sync API для загрузки локальных файлов, таких как фотографии, в аккаунт Dropbox.
На каждой из этих связанных страниц есть ссылки для загрузки соответствующего SDK, а также учебники, в которых показано, как загружать и скачивать файлы.
Вы на полпути, если у вас есть файл на SD-карте (или просто есть InputStream для него).
Я не могу поручиться за Dropbox, но вот пример подключения к Google Drive и загрузки сделанного снимка. Все в одном месте без использования каких-либо вспомогательных методов.
Примечание. Вам все еще нужно выполнить руководство по интеграции с Google Drive.
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><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /></code>
* <li><code><uses-permission android:name="android.permission.CAMERA" /></code>
* <li><code><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);
}
}
}
}
}
}