我正在开发一个OCR应用程序,在从相机获取实时更新并找到所需文本后,我开始了一个"报告活动"将OCR的结果报告给用户。它工作正常,但我想让应用程序在更改活动之前拍摄相机的图片。我包含了我当前的Java类,我在PictureCallback中启动了活动。问题是,有时应用程序会更改活动,而其他应用程序(和调试程序)只会冻结。非常感谢帮助理解为什么会发生这种情况以及如何解决它。
来自OpticalProcessor类(活动是初始化期间传递的当前活动)
@Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
Intent intent = new Intent(activity.getBaseContext(), ReportActivity.class);
int flag = 0;
//Perform OCR Processing
if (flag > 3) {
Log.d("Test", "Testing 1234454");
startAct(intent, activity);
}
}
private void startAct (final Intent intent, final Activity act) {
((OcrCaptureActivity) activity).mCameraSource.takePicture(new com.embocorp.utils.receipt.ocrreader.ui.camera.CameraSource.ShutterCallback() {
@Override
public void onShutter() {
Log.d("New", "New");
}
}, new com.embocorp.utils.receipt.ocrreader.ui.camera.CameraSource.PictureCallback() {
@Override
public void onPictureTaken(byte[] data) {
Log.d("Move", "mobe");
Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
saveToInternalStorage(bmp, getCurrentTimeStamp(), act, intent);
act.startActivity(intent);
}
});
}
private String saveToInternalStorage(Bitmap bitmapImage, String name) {
ContextWrapper cw = new ContextWrapper(activity.getApplicationContext());
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
File mypath=new File(directory, name + ".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
答案 0 :(得分:1)
据我所知,我不知道为什么有什么东西在冻结。你很可能在某个地方锁定了UI线程。
就问题标题而言:如果您的回调设置正确,异步代码将得到最佳处理。
例如,我看到你有一对高度耦合的类,其中一个只有一堆回调处理相机。
我的建议是没有显式的Activity,你试图访问该类的任何字段。例如((OcrCaptureActivity) activity).mCameraSource.takePicture
,而如果你真的需要那个类(或者更确切地说是mCameraSource
),那么你应该给出它。另一方面,活动本身可以实现这些回调,这就是startActivity
和所有这些事情的所在。
import com.embocorp.utils.receipt.ocrreader.ui.camera.CameraSource;
public class OpticalProcessor {
// TODO: Implement other interfaces here for receiveDetections method?
private final Context mContext;
private CameraSource.ShutterCallback shutterCallback;
private CameraSource.PictureCallback pictureCallback;
private OnDetectionsReceievedListener detectionListener;
public interface OnDetectionsReceievedListener {
void onDetectionsReceived(Detector.Detections<TextBlock> detections);
}
public OpticalProcessor(Context c) {
this(c, null, null);
}
public OpticalProcessor(Context c, CameraSource.ShutterCallback shutterCallback, CameraSource.PictureCallback pictureCallback) {
this.mContext = c;
setShutterCallback(shutterCallback);
setPictureCallback(pictureCallback);
}
public void takePicture(CameraSource camera) {
if (this.shutterCallback != null && this.pictureCallback != null) {
camera.takePicture(this.shutterCallback, this.pictureCallback);
} else {
Log.w("OpticalProcessor::takePicture", "Shutter or Picture callbacks have not been set!");
}
}
public void setShutterCallback(CameraSource.ShutterCallback shutterCallback) {
this.stutterCallback = shutterCallback;
}
public void setPictureCallback(CameraSource.PictureCallback pictureCallback) {
this.pictureCallback = pictureCallback;
}
public void setDetectionListener(CameraSource.PictureCallback pictureCallback) {
this.detectionListener = detectionCallback;
}
@Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
// Maybe this is needed?
if (detectionListener != null) {
detectionListener.onDetectionsReceived(detections);
}
// Perform OCR Processing
int tag = 0;
if (tag > 3) { // Why would this have worked? It's set at 0...
Log.d("Test", "Testing 1234454");
}
}
}
正如我所说,Activity实现了回调并将它们传递到相应的位置。
我假设您正在尝试拍摄照片以响应某些点击事件。
import com.embocorp.utils.receipt.ocrreader.ui.camera.CameraSource;
public class OcrCaptureActivity extends Activity
implements CameraSource.ShutterCallback, CameraSource.PictureCallback,
OpticalProcessor.OnDetectionsReceievedListener {
private CameraSource mCameraSource;
@Override
public void onCreate(Bundle b) {
super.onCreate(b);
// setContentLayout...
...
mCameraSource = ???
// Pass the context and the listeners here
final OpticalProcessor processor = new OpticalProcessor(this, this, this);
processor.setDetectionListener(this);
someButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
processor.takePicture(mCameraSource);
}
});
}
// This method could really be anywhere as long as it has a Context
public static String saveToInternalStorage(Context ctx, Bitmap bitmapImage, String name) {
File directory = ctx.getDir("imageDir", Context.MODE_PRIVATE);
File path=new File(directory, name + ".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path);
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
@Override
public void onShutter() {
Log.d("New", "New");
}
@Override
public void onPictureTaken(byte[] data) {
Log.d("Move", "mobe");
Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
saveToInternalStorage(this, bmp, getCurrentTimeStamp());
// Activity started here
startActivity(new Intent(this, ReportActivity.class));
}
@Override
public void onDetectionsReceived(Detector.Detections<TextBlock> detections) {
// Perform OCR Processing??
}
}