您好我想开发一款可拍照并上传到Google云端硬盘的应用。我今天从Github找到了主人(源代码),这是由谷歌https://github.com/googledrive/android-quickstart
这非常有用。但我发现了一些问题,如果我按下后退按钮,应用程序仍然无法完成它的活动。默认情况下,它始终打开相机并拍照并将其保存到Google云端硬盘。它会一次又一次地做同样的事情。如果我要退出应用程序,我不能按Home键。任何解决方案?还有另一个问题:拍照后它会显示一个对话框窗口,询问保存图像的位置以及图像名称。问题是如果按下取消按钮则显示相同对话一次又一次。如果我按下确定然后它不会显示对话框,但如果我按下取消它再次显示相同的对话框。当我按下取消时,我想摆脱它。有解决方案吗这是代码:
package com.randb.uploadtogdrive;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi.ContentsResult;
import com.google.android.gms.drive.MetadataChangeSet;
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 GoogleApiClient mGoogleApiClient;
private Bitmap mBitmapToSave;
/**
* Create a new file and save it to Drive.
*/
private void saveFileToDrive() {
// Start by creating a new contents, and setting a callback.
Log.i(TAG, "Creating new contents.");
final Bitmap image = mBitmapToSave;
Drive.DriveApi.newContents(mGoogleApiClient).setResultCallback(new ResultCallback<ContentsResult>() {
@Override
public void onResult(ContentsResult result) {
// If the operation was not successful, we cannot do anything
// and must
// fail.
if (!result.getStatus().isSuccess()) {
Log.i(TAG, "Failed to create new contents.");
return;
}
// Otherwise, we can write our data to the new contents.
Log.i(TAG, "New contents created.");
// Get an output stream for the contents.
OutputStream outputStream = result.getContents().getOutputStream();
// Write the bitmap data from it.
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
} catch (IOException e1) {
Log.i(TAG, "Unable to write file contents.");
}
// Create the initial metadata - MIME type and title.
// Note that the user will be able to change the title later.
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("image/jpeg").setTitle("myPhoto.png").build();
// Create an intent for the file chooser, and start it.
IntentSender intentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialContents(result.getContents())
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.i(TAG, "Failed to launch file chooser.");
}
}
});
}
@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
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
@Override
public void onBackPressed(){
Toast.makeText(MainActivity.this,"Going Somehwere?", Toast.LENGTH_LONG).show();
finish();
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_CAPTURE_IMAGE:
// Called after a photo has been taken.
if (resultCode == Activity.RESULT_OK) {
// Store the image data as a bitmap for writing later.
mBitmapToSave = (Bitmap) data.getExtras().get("data");
}
break;
case REQUEST_CODE_CREATOR:
// Called after a file is saved to Drive.
if (resultCode == RESULT_OK) {
Log.i(TAG, "Image successfully saved.");
mBitmapToSave = null;
// // Just start the camera again for another photo.
// startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
// REQUEST_CODE_CAPTURE_IMAGE);
}
break;
}
}
@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.
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) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
@Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "API client connected.");
if (mBitmapToSave == null) {
// This activity has no UI of its own. Just start the camera.
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
REQUEST_CODE_CAPTURE_IMAGE);
return;
}
saveFileToDrive();
}
@Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
答案 0 :(得分:0)
以下是您的问题的快速解决方法。你正在谈论的两个活动的后退按钮(相机,创建者)返回'Activity.RESULT_CANCELED',所以当你没有得到'Activity.RESULT_OK'时,只需要杀死你的活动(使用finish())。
switch (requestCode) {
case REQUEST_CODE_CAPTURE_IMAGE:
// Called after a photo has been taken.
if (resultCode == Activity.RESULT_OK) {
// Store the image data as a bitmap for writing later.
mBitmapToSave = (Bitmap) data.getExtras().get("data");
} else
finish();
break;
case REQUEST_CODE_CREATOR:
// Called after a file is saved to Drive.
if (resultCode == RESULT_OK) {
Log.i(TAG, "Image successfully saved.");
mBitmapToSave = null;
// // Just start the camera again for another photo.
// startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
// REQUEST_CODE_CAPTURE_IMAGE);
} else
finish();
break;
}
但总的来说,“快速启动”通常只是一个概念验证,而不是你应该为你构建app的东西。
答案 1 :(得分:0)
这应该照顾你'缩略图'的问题。基本上,将位图 mBitmapToSave 替换为文件'_picFl'。下面的代码被修改,var名称不同,但它基本上是你要求的。
private File _picFl;
private GoogleApiClient _gac;
@Override public void onConnected(Bundle connectionHint) {
if (_picFl == null)
takePic();
else
save2GooDrv();
}
//-----------------------------------------------------------------------------------------------
private void takePic() {
Intent icIt = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (icIt.resolveActivity(getPackageManager()) != null) try {
_picFl = new File(getCcheDir(), tm2FlNm(null));
if (_picFl != null) {
icIt.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(_picFl));
startActivityForResult(icIt, RC_GETIMAGE);
}
} catch (Exception e) {le(e);}
}
//-----------------------------------------------------------------------------------------------
private synchronized void save2GooDrv() {
Drive.DriveApi.newContents(_gac).setResultCallback(new ResultCallback<ContentsResult>() {
@Override public void onResult(ContentsResult rslt) {
if (rslt.getStatus().isSuccess()) try {
OutputStream os = rslt.getContents().getOutputStream();
os.write(file2Bytes(_picFl));
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("image/jpeg").setTitle(_picFl.getName()).build();
_picFl.delete();
_picFl = null;
IntentSender intentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialContents(rslt.getContents())
.build(_gac);
try {
startIntentSenderForResult( intentSender, RC_CREATOR, null, 0, 0, 0);
} catch (SendIntentException e) {le(e);}
} catch (Exception e) {le(e);}
}
});
}
//***********************************************************************************************
public String getCcheDir() {
Context actx = getApplicationContext();
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
!Environment.isExternalStorageRemovable() ?
actx.getExternalCacheDir().getPath() : actx.getCacheDir().getPath();
}
//***********************************************************************************************
public byte[] file2Bytes(File file) {
byte[] buf = null;
RandomAccessFile raFl = null;
if (file != null) try {
raFl = new RandomAccessFile(file, "r");
buf = new byte[(int)raFl.length()];
raFl.readFully(buf);
} catch (Exception e) {le(e);}
finally {
if (raFl != null) try {
raFl.close();
} catch (Exception e) {le(e);}
}
return buf;
}
//***********************************************************************************************
public String tm2FlNm(Long milis) { // time -> yymmdd-hhmmss
try {
return new SimpleDateFormat("yyMMdd-HHmmss",Locale.US)
.format((milis == null) ? new Date() : new Date(milis));
} catch (Exception e) {le(e);}
return null;
}
//***********************************************************************************************
public void le(Exception e){
try {
Log.e("_", (e==null) ? "NULL" : Log.getStackTraceString(e));
}catch (Exception f) { try { Log.e("_", "ERR on err");} catch (Exception g) {} }
}