not - Android onActivityResult no se llama/desencadena
startactivityforresult fragment (8)
Leí mucho sobre los problemas con onActivityResult
, pero parece que ninguno de los problemas descritos encaja con el mío, como poner un startActivityForResult
de startActivityForResult
negativo en startActivityForResult
o algo más.
Estoy jugando con la cámara en mi actividad, que transmite su vista previa a un SurfaceView. Después de tomar una foto, cierro la cámara liberando sus recursos, llamo a setResult(RESULT_OK, DataIntent)
y espero que onActivityResult
se onActivityResult
en mi padre.
Pero no lo hace. Si configuro un resultado en onCreate
de la actividad del niño y finalizo el niño en onCreate, el resultado no se pasa a onActivityResult.
¿Qué razón posible podría ser que onActivityResult
no se onActivityResult
? Escribiré algo de mi fuente para entender lo que estoy haciendo ...
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;
}
}
¿Puede ser que tu actividad anterior no termine? Intente realizar la depuración con Log.d y vea logcat para ver si la pila de llamadas realmente llega a la declaración final () en su clase CaptureActivity.
Asegúrese de que el parámetro de número pasado a startActivityForResult(...)
es> = 0
Eliminando android:noHistory="true"
de la actividad que estaba teniendo problema, resolví el problema por mí.
En mi caso, no se activó porque había agregado el indicador Intent.FLAG_ACTIVITY_NEW_TASK
al crear la intención de startActivityForResult
. Eliminándolo resolví mi problema.
Otra variante en este caso. Desde un DialogFragment, puede "startActivityForResult". Pero si su Intención se inicia desde la Actividad asociada, debe incluir "getActivity ()" antes de startActivityForResult. Ver abajo (última línea).
Activity activeOne=FileDialogWindow.this.getActivity();
Intent intent = new Intent(activeOne,FolderSelectionActivity.class);
String message = "foobar";
intent.putExtra(EXTRA_MESSAGE, message);
getActivity().startActivityForResult(intent,1);
Resolví el problema yo mismo ahora.
Después de renunciar a la activación onActivityResult
, decidí "piratear" los androides encapsulando pasando una referencia estática de MainActivity a CaptureActivity, incluso si sé que no es una buena idea.
Después de la llamada finish()
, MAGICALLY onActivityResult
se activa con Context.RESULT_CANCELLED
... como se esperaba porque ya no llamo setResult
.
Obteniendo onActivityResult
desencadenado, investigué por qué está funcionando ahora. Descubrí, que tiene algo que ver con el mapa de bits, pasado a un Intent. Si pongo un Parcellable
bits Parcellable
en mi resultado, el onActivityResult
en la onActivityResult
nunca se dispara.
Así que quitar la siguiente línea en el código anterior funcionará:
intent.putExtra(Config.SCAN_RESULT_BMP, barcode);
Eso está bien para mí, porque realmente no necesitaba el BitMap en esta otra actividad. Era más una "característica" que una necesidad.
Si algunos de ustedes quieren pasar Big Data a un Intent
como un Bitmap
, piense en almacenarlo en algún lugar en SD, pasando la ruta en el Intent, mientras lee este Bitmap
de SD en ParentActivity ( Cómo tomar una foto por Intent ).
Como se indica here , el límite de un Parcelable
es de 1 MB, por lo tanto, todo lo que se pase a un Intent
provocará una TransactionTooLargeException
interna y fallará en silencio
Tenía el mismo problema. revise su manifiesto y asegúrese de que NO está utilizando una sola instancia:
android:launchMode="singleInstance"
en mi caso, el código de solicitud de escaneo debe ser IntentIntegrator.REQUEST_CODE ,
es decir
startActivityForResult(intent, IntentIntegrator.REQUEST_CODE)
.
La esperanza te puede ayudar.