Frage Android Kamera API App stürzt bei onResume ab


Ich benutze die Kamera-API, um eine App zu schreiben: Vorschau anzeigen und ein Foto machen. Die erste Version funktioniert sehr gut. In der Klasse Preview erweitert SurfaceView SurfaceHolder.Callback

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    camera = Camera.open();
    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();

    } catch (IOException e) {
        e.printStackTrace();
    }

    hasSurface = true;
}


public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // It will be called immediately after surfaceCreated
    // I move it to Resume.
    setCameraPreviewParameters();

    camera.startPreview();

}

In der Haupttätigkeit:

public class CameraDemo extends Activity

Ich habe auch ein Mitglied gesetzt: KameraUnit ui; Es ist:

public class CameraUnit extends LinearLayout

Im onCreate,

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ui = new CameraUnit(this);
    setContentView((View) ui); 

    Log.d(TAG, "onCreate'd");
}

Es erstellt ein LinearLayout-Objekt, das die Oberflächenansicht und eine Kamera-Schaltfläche enthält.

Das onResume ist:

    @Override
protected void onResume() {
    super.onResume();
}

Obwohl es funktioniert, denke ich, dass das onResume nicht leer sein sollte. Ich sehe auch die OberflächeCreated und SurfaceChanged sind leer in einem berühmte Android App Beispiel OCRTest Ich glaube also, es ist besser und auch machbar, die Befehle in SurfaceCreated und SurfaceChanged in onResume zu verschieben.

Ich denke, der Flow-Chat für die 1. Version meiner App sollte sein: Hauptaktivität onCreate (wo das LinearLayout und seine OberflächeView, Kamera-Schaltfläche erstellt werden), OberflächeCreated und SurfaceChanged heißen: auf Wiederaufnahme.

So kann ich einfach die Befehle in SurfaceCreated und SurfaceChanged in onResume verschieben. Aber es funktioniert nicht! Ich habe Debug verwendet, um herauszufinden, dass die Oberfläche null ist. Ich denke der SurfaceCreatd wird nicht aufgerufen. Meine App ist ein anderer OCRTest, der SurfaceHolder.Callback in der Hauptaktivität implementiert. Ich implementiere SurfaceHolder.Callback in der SurfaceView:

class Preview extends SurfaceView implements SurfaceHolder.Callback

Also füge ich zwei weitere Zeilen in onResume hinzu

        ui.preview.surfaceCreated(ui.preview.mHolder);
    ui.preview.surfaceChanged(ui.preview.mHolder, 0, 800, 400);

Ich setze zufällig die letzten drei ganzzahligen Argumente. Wenn ich die Aktivität starte, erscheint das Fehlerfenster im Android-Telefon. Es heißt "verursacht durch: java.lang.RuntimeException: Verbindung zum Kamera-Dienst konnte nicht hergestellt werden". Aber wie man es repariert ???? Danke vielmals!

Fehler sind:

    01-07 00:27:57.173: W/dalvikvm(11625): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
01-07 00:27:57.173: E/AndroidRuntime(11625): FATAL EXCEPTION: main
01-07 00:27:57.173: E/AndroidRuntime(11625): java.lang.RuntimeException: Unable to resume activity {com.example/com.example.CameraDemo}: java.lang.RuntimeException: Fail to connect to camera service
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2460)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2481)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1847)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.access$1500(ActivityThread.java:132)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.os.Looper.loop(Looper.java:150)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.main(ActivityThread.java:4263)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at java.lang.reflect.Method.invokeNative(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at java.lang.reflect.Method.invoke(Method.java:507)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at dalvik.system.NativeStart.main(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625): Caused by: java.lang.RuntimeException: Fail to connect to camera service
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.native_setup(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.<init>(Camera.java:265)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.open(Camera.java:241)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.example.Preview.surfaceCreated(Preview.java:60)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.example.CameraDemo.onResume(CameraDemo.java:64)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1242)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.Activity.performResume(Activity.java:3904)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2450)
01-07 00:27:57.173: E/AndroidRuntime(11625):    ... 12 more
01-07 00:27:59.455: I/Process(11625): Sending signal. PID: 11625 SIG: 9

5
2018-01-07 06:36


Ursprung


Antworten:


Du bekommst das

java.lang.RuntimeException: Fail to connect to camera service

Ausnahme, wenn die Kamera von anderen Anwendungen verwendet wird. Aber ich glaube, dass andere Anwendung Ihre Anwendung selbst ist. Sie müssen die Kamera loslassen.

In diesen Fällen sollten Sie die Kamera freigeben:

In der Vorschau Klasse:

public void surfaceDestroyed(SurfaceHolder holder) {

    // empty. Take care of releasing the Camera preview in your activity.
    if (mCamera != null) {
        mCamera.release();
    }
}

In der Aktivität:

@Override
public void onBackPressed() {
    super.onBackPressed();
    if (myCamera != null) {
        myCamera.release();
    }
    finish();
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if (myCamera != null) {
        myCamera.release();
    }
}

Ebenfalls auf Abbrechen geklickt, und auch wenn Sie mit der Kamera fertig sind, z. B. wenn das Bild aufgenommen wurde und Sie zur Aktivität zurückkehren.

Versuchen Sie es auch:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (mHolder.getSurface() == null) {
        return;
    }

    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        //You can ignore this, because this means the Preview doesn't Exist
        //So, no need to try stopping
    }

    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        //Catch this
    }
}

5
2018-01-07 06:43



Also habe ich eine App erstellt, die die Kamera verwendet, aber ein anderes Start-Icon, um auf die Einstellungsseite zu gelangen. Jedes Mal, wenn ich die App pausierte und minimierte, um die Einstellungen zu ändern, ging sie auch mit diesem Fehler zurück. Nach vielen Recherchen hatte ich immer noch keine Antwort. Dann erkannte ich, dass dies mit der Verwaltung des Lebenszyklus der Kamera zu tun hatte. So ging und schaute auf den Lebenszyklus, speziell auf Anhalten. Also habe ich realisiert, dass wir alle auf die falsche Methode gehen. Wo wir es auf dem onResume machen, sollten wir es auf Start tun. UND BAM! es funktionierte.

Hier ist mein Code für meine App.

@Override
    protected void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
        if (mPreview != null) {
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer);
            preview.removeView(mPreview);
            mPreview = null;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
        if (mPreview != null) {
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer);
            preview.removeView(mPreview);
            mPreview = null;
        }
    }
    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onStart(){
        super.onStart();
//Check if the camera exists or not so it does not clash with the onCreate
        if(mCamera == null){
            dir_string =  new File("/storage/sdcard1/app");
            Log.d("TAG",dir_string.toString());
            mCamera = getCameraInstance();
            mPreview = new CameraPreview(this, mCamera);
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer);
            preview.addView(mPreview);
        }
    }

Hoffe, das hilft wenigstens jemandem.


1
2017-07-22 14:15



Ich finde in einigen Beispielen, dass der offene Code der Kamera sowohl in der Oberfläche als auch in der OnResume enthalten ist, wobei ein if-Satz verwendet wird, um Wiederholungen zu vermeiden. Vielleicht ist dies eine Möglichkeit, das Problem zu lösen.


0
2018-01-16 18:13