我阅读了很多关于onActivityResult
的问题,但似乎没有任何描述的问题适合我的,例如在startActivityForResult
或其他内容中添加否定的requestCode。
我在我的Activity中使用相机,它将预览流式传输到SurfaceView。
拍照后,我关闭凸轮释放其资源,调用setResult(RESULT_OK, DataIntent)
并希望在我的父母中触发onActivityResult
。
但事实并非如此。如果我在子Activity的onCreate
中设置结果并在onCreate中完成子项,则结果不会传递给onActivityResult。
onActivityResult
不被触发的可能原因是什么?
我会写下我的一些资料来理解我正在做的事情......
public class MainActivity extends Activity {
Button mButtonScan;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButtonScan = (Button)findViewById(R.id.main_btn_scan);
}
/**
* OnClick Event called from main.xml
* @param v View that called that onClickEvent
*/
public void btnCaptureClick(View v) {
Intent intent = new Intent(this, CaptureActivity.class);
startActivityForResult(intent, Constants.REQUEST_CODE_CAPTURE);
}
/**
* callback for this Activity. Called when an Activity which was started by
* this.startActivityForResult(intent, requestCode) sets its result and calls finish()
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
String foo = "foo";
switch (requestCode) {
case Constants.REQUEST_CODE_CAPTURE:
switch (resultCode) {
case RESULT_FIRST_USER:
Toast.makeText(this, data.getStringExtra(Config.SCAN_RESULT_TEXT), Toast.LENGTH_LONG).show();
break;
case RESULT_CANCELED:
break;
default:
break;
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
}
public class CaptureActivity extends Activity implements ActivityCallback, SurfaceHolder.Callback, PreviewCallback {
private Preview mPreview;
private Camera mCam;
private SurfaceHolder mHolder;
private Size size;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.capture);
mPreview = (Preview)findViewById(R.id.capture_preview);
}
@Override
public void onValidDecodeResult(Result rawResult, Bitmap barcode) {
Intent intent = new Intent();
if (rawResult != null && barcode != null) {
intent.putExtra(Config.SCAN_RESULT_TEXT, rawResult.getText());
intent.putExtra(Config.SCAN_RESULT_FORMAT, rawResult.getBarcodeFormat().getName());
intent.putExtra(Config.SCAN_RESULT_BMP, barcode);
} else {
intent.putExtra(Config.SCAN_RESULT_TEXT, "foo");
intent.putExtra(Config.SCAN_RESULT_FORMAT, "bar");
intent.putExtra(Config.SCAN_RESULT_BMP, "barcode");
}
mPreview = null;
setResult(Activity.RESULT_FIRST_USER, intent);
finish();
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
MultiFormatReader reader = new MultiFormatReader();
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, size.width, size.height, 160, 60, 480, 360);
GlobalHistogramBinarizer binarizer = new GlobalHistogramBinarizer(source);
BinaryBitmap bb = new BinaryBitmap(binarizer);
Result result = null;
try {
result = reader.decode(bb);
} catch (NotFoundException e) {
//do NOTHING cause e == null
} catch (Exception e){
e.printStackTrace();
} finally {
reader.reset();
}
if (result != null) {
mCam.stopPreview();
releaseCameraResources();
onValidDecodeResult(result, source.renderCroppedGreyscaleBitmap());
} else {
camera.setOneShotPreviewCallback(this);
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCam = Camera.open();
mCam.setPreviewDisplay(mPreview.getHolder());
} catch (IOException e) {
releaseCameraResources();
e.printStackTrace();
}
}
private void releaseCameraResources() {
mCam.release();
mCam = null;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
//begin Preview
Camera.Parameters parameters = mCam.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
size = getOptimalPreviewSize(sizes, width, height);
parameters.setPreviewSize(size.width, size.height);
mCam.setParameters(parameters);
mCam.startPreview();
mCam.setOneShotPreviewCallback(this);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCam != null) {
mCam.stopPreview();
releaseCameraResources();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int width, int height) {
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) width / height;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = height;
for (Size size: sizes) {
double ratio = (double) size.width / size.height;
if(Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {
continue;
}
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
//cannot find matching aspect-ratio
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
}
答案 0 :(得分:49)
确保传递给requestCode
的数字参数(startActivityForResult(...)
)为&gt; = 0
答案 1 :(得分:36)
有同样的问题。检查您的清单并确保您没有使用单个实例:
android:launchMode="singleInstance"
答案 2 :(得分:23)
从我遇到问题的活动中删除android:noHistory="true"
为我解决了这个问题。
答案 3 :(得分:18)
我现在自己解决了这个问题。
在放弃获得onActivityResult
触发后,我决定通过将MainActivity的静态引用传递给CaptureActivity来“破解”Androids封装,即使我知道这不是一个好主意。
finish()
来电之后,onActivityResult
Context.RESULT_CANCELLED
被setResult
触发......正如预期的那样,因为我不再呼叫onActivityResult
。
获取Parcellable
触发我调查了它现在正在运作的原因。我发现,它与位图有关,传递给Intent。如果我将onActivityResult
位图放入我的resultIntent intent.putExtra(Config.SCAN_RESULT_BMP, barcode);
,则永远不会被解雇。
因此,删除上面代码中的以下行将起作用:
Intent
这对我来说没问题,因为我在其他Activity中并不需要BitMap。它更像是一种“特征”而非需求。
如果有些人想要将大数据传递到像Bitmap
这样的Bitmap
,请考虑将其存储在SD上的某处,在Intent中传递路径,同时阅读{{1}来自ParentActivity中的SD(How to take a photo by Intent)。
如上所述here,Parcelable
的限制为1MB,因此传递给Intent
的所有内容都会导致内部 TransactionTooLargeException
并将默默地失败
答案 4 :(得分:3)
在我的情况下,由于我在为Intent.FLAG_ACTIVITY_NEW_TASK
创建意图时添加了标记startActivityForResult
,因此未触发。删除它解决了我的问题。
答案 5 :(得分:3)
这一个的另一个变种。从DialogFragment,您可以startActivityForResult
。但是,如果您的Intent是从关联的Activity启动的,那么您必须在getActivity()
之前添加startActivityForResult
。见下文(最后一行):
Activity activeOne=FileDialogWindow.this.getActivity();
Intent intent = new Intent(activeOne,FolderSelectionActivity.class);
String message = "foobar";
intent.putExtra(EXTRA_MESSAGE, message);
getActivity().startActivityForResult(intent,1);
答案 6 :(得分:1)
可能就是您以前的活动没有完成的情况?尝试使用Log.d进行调试并查看logcat以查看调用堆栈是否实际到达CaptureActivity类中的finish()语句。
答案 7 :(得分:0)
在我的情况下,扫描请求代码必须是 IntentIntegrator.REQUEST_CODE ,
即
startActivityForResult(intent, IntentIntegrator.REQUEST_CODE)
。