Kamera nach Kamera.release() aufgerufen wurde in Galaxy s6 Edge
Habe ich die folgende Ausnahme auf Galaxy s6 edge-Gerät
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.setPreviewSurface(Native Method)
at android.hardware.Camera.setPreviewDisplay(Camera.java:702)
at com.forsale.forsale.view.uicomponent.qrcode.CameraPreview.surfaceCreated(CameraPreview.java:59)
at android.view.SurfaceView.updateWindow(SurfaceView.java:712)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:316)
at android.view.View.dispatchWindowVisibilityChanged(View.java:10434)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1750)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1437)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7397)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
at android.view.Choreographer.doCallbacks(Choreographer.java:695)
at android.view.Choreographer.doFrame(Choreographer.java:631)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
dies ist mein code :
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private PreviewCallback previewCallback;
private AutoFocusCallback autoFocusCallback;
public CameraPreview(Context context, Camera camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
super(context);
mCamera = camera;
previewCallback = previewCb;
autoFocusCallback = autoFocusCb;
/*
* Set camera to continuous focus if supported, otherwise use
* software auto-focus. Only works for API level >=9.
*/
/*
Camera.Parameters parameters = camera.getParameters();
for (String f : parameters.getSupportedFocusModes()) {
if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
autoFocusCallback = null;
break;
}
}
*/
//Install a SurfaceHolder.Callback so we get notified when the
//underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
//deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
//The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
Log.d("DBG", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
//Camera preview released in activity
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
/*
* If your preview can change or rotate, take care of those events here.
* Make sure to stop the preview before resizing or reformatting it.
*/
if (mHolder.getSurface() == null){
//preview surface does not exist
return;
}
//stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
//ignore: tried to stop a non-existent preview
}
try {
//Hard code camera surface rotation 90 degs to match Activity view in portrait
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e){
Log.d("DBG", "Error starting camera preview: " + e.getMessage());
}
}
}
dies ist der code der Aktivität
public class QRCodeActivity extends BaseActivity
{
private Camera mCamera;
private CameraPreview mPreview;
private Handler mAutoFocusHandler;
private ImageScanner mScanner;
private boolean mBarcodeScanned = false;
private boolean mPreviewing = true;
static {
System.loadLibrary("iconv");
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qrcode);
initializeActionBar();
setActionBarTitle(getString(R.string.qrcode));
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mAutoFocusHandler = new Handler();
mCamera = getCameraInstance();
mScanner = new ImageScanner();
mScanner.setConfig(0, Config.X_DENSITY, 3);
mScanner.setConfig(0, Config.Y_DENSITY, 3);
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
}
public void onPause() {
super.onPause();
releaseCamera();
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
} catch (Exception e){
}
return c;
}
private void releaseCamera() {
if (mCamera != null) {
mPreviewing = false;
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (mPreviewing)
mCamera.autoFocus(autoFocusCB);
}
};
PreviewCallback previewCb = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = mScanner.scanImage(barcode);
if (result != 0) {
mPreviewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = mScanner.getResults();
for (Symbol sym : syms) {
showProgressDialog();
ForSaleServerManager.getInstance().verifyQRCode(QRCodeActivity.this, PhoneUtils.getDeviceId(QRCodeActivity.this) , sym.getData() , new VerifyQRCodeUIListener() {
@Override
public void onVerifyQRCodeCompleted(QRCodeResponse response, AppError error) {
hideProgressDialog();
if (error != null) {
DialogUtils.showDialogMessage(
QRCodeActivity.this,
getString(R.string.error),
PhoneUtils.getErrorMessage(QRCodeActivity.this, error),
getString(R.string.ok), null);
} else {
if (response != null && response.getError() == null) {
DialogUtils.showDialogMessage(QRCodeActivity.this, getString(R.string.info),
response.getMessage(), getString(R.string.ok), new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
} else if (response != null && response.getError() != null) {
DialogUtils.showDialogMessage(
QRCodeActivity.this,
getString(R.string.error),
response.getError().getMessage(),
getString(R.string.ok), null);
}
}
}
});
mBarcodeScanned = true;
}
}
}
};
AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
@Override
protected void initializeUIComponents() {
}
@Override
protected void initializeUIComponentsData() {
}
@Override
protected void initializeUIComponentsTheme() {
}
@Override
protected void initializeUIComponentsAction() {
}
@Override
public void goodTimeToReleaseMemory() {
/*mCamera = null;
mPreview = null;
mAutoFocusHandler = null;
mScanner = null;*/
Runtime.getRuntime().gc();
finish();
}
}
vielleicht hatten Sie genannt-Kamera.release() auf eine frühe version, so deinstallieren Sie die app vom Gerät, reinigen Sie Ihr Projekt und installieren Sie es erneut. Nach
Haben Sie Kamera.open() in Start-Methode?
wo ist die Kamera öffnen ? ich denke, Sie müssen re-öffnen Sie die Kamera zunächst nach Ihrer Kamera Aktivität angehalten wird / zerstört.
Ich bin nicht sicher, ob ich verstehe, was jetzt fehlt. Sie veröffentlicht Ihren code, aber was tun Sie jetzt?
release()
aufgerufen wird, müssen Sie initialisieren das Objekt wieder....Haben Sie Kamera.open() in Start-Methode?
Camera.open(id)
und mCamera.release()
sollte Teil der Choreographie. Ich bevorzuge es, zu initiieren, öffnen Sie() auf einem hintergrund looper von surfaceCreated()
wo ist die Kamera öffnen ? ich denke, Sie müssen re-öffnen Sie die Kamera zunächst nach Ihrer Kamera Aktivität angehalten wird / zerstört.
Ich bin nicht sicher, ob ich verstehe, was jetzt fehlt. Sie veröffentlicht Ihren code, aber was tun Sie jetzt?
InformationsquelleAutor Amira Elsayed Ismail | 2016-06-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist ein ernster Fehler in deinem code:
mCamera.release()
heißt auf jeden onPause, aberCamera.open()
wird nur aufgerufen, onCreate.Dieser sagte, ist es eine schlechte Praxis zu öffnen, die Kamera auf die Haupt (UI) - thread: dieser Aufruf kann zu lange dauern, auf einigen Geräten (nicht auf dem Samsung Galaxy 6) und sogar dazu führen, ANR.
Ist die beste Methode zu öffnen, die Kamera auf einem hintergrund HandlerThread (siehe https://stackoverflow.com/a/19154438/192373). Dies wird garantieren, dass die Kamera Rückrufe (einschließlich
onPictureTaken()
) nicht einfrieren Ihre UI-thread.Jedenfalls halten die mCamera Objekt synchronisiert mit dem Lebenszyklus Ihrer Aktivität und Ihren SurfaceView, empfehle ich zu Beginn
Camera.open()
aus surfaceCreated undmCamera.release()
- von surfaceDestroyed.InformationsquelleAutor Alex Cohn