Problem mit CameraPreview: An error occurred while connecting to camera: 0

  • Antworten:8
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 607

16.12.2015, 20:04:26 via Website

Hallo Leute,

meine App soll ein Vollbild-CameraPreview direkt beim Starten der App anzeigen. Leider funktioniert das nicht so ganz wie es soll. Die App schließt sofort wieder.

Inhalt der MainActivity:

public class MainActivity extends AppCompatActivity{

private static final String LOG = "MainActivity.java";

private Camera mCamera;
private CameraPreview mPreview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FloatingActionButton fabPref = (FloatingActionButton) findViewById(R.id.fabPref);
    fabPref.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });

    FloatingActionButton fabPhoto = (FloatingActionButton) findViewById(R.id.fabPhoto);
    fabPhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });

    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);


    if(checkCameraHardware(this)==true){
        Log.e("CAMERA", "vorhanden");


        // Create an instance of Camera
        mCamera = getCameraInstance();
        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        preview.addView(mPreview);

    }else{
        Log.e("CAMERA", "nicht vorhanden");
    }

}

private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        return true;
    } else {
        return false;
    }
}

public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
        Log.e(LOG, "CameraInstance: " + c + " RUNS");
    }
    catch (Exception e){
        Log.e(LOG, "Camera not available");
        Log.e(LOG, "CameraInstance: " + c);
    }
    Log.e(LOG, "CameraInstance: " + c);

    return c; // returns null if camera is unavailable


}

}

Inhalt der CameraPreview.java:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private static final String TAG = "CameraPreview.java";

private SurfaceHolder mHolder;
private Camera mCamera;

public CameraPreview(Context context, Camera camera) {
    super(context);
    mCamera = camera;

    // 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);
        mCamera.startPreview();
    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // empty. Take care of releasing the Camera preview in your activity.
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // 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
    }

    // set preview size and make any resize, rotate or
    // reformatting changes here

    // start preview with new settings
    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();

    } catch (Exception e){
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}

}

Inhalt des LogCats:

a quote goes here12-16 19:54:06.621 13572-13572/de.aintlarry.shotanalysis I/art: Late-enabling -Xcheck:jni
12-16 19:54:06.622 13572-13572/de.aintlarry.shotanalysis I/art: VMHOOK: rlim_cur : 0 pid:13572
12-16 19:54:06.717 13572-13572/de.aintlarry.shotanalysis W/System: ClassLoader referenced unknown path: /data/app/de.aintlarry.shotanalysis-2/lib/arm64
12-16 19:54:06.834 13572-13572/de.aintlarry.shotanalysis E/CAMERA: vorhanden
12-16 19:54:06.847 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:07.149 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:07.450 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:07.751 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:08.052 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis I/Camera2Mode: fail
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis E/MainActivity.java: Camera not available
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis E/MainActivity.java: CameraInstance: null
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis E/MainActivity.java: CameraInstance: null
12-16 19:54:08.430 13572-13621/de.aintlarry.shotanalysis I/Adreno: QUALCOMM build : 8e7809e, Ic2ca81afa7
Build Date : 09/18/15
OpenGL ES Shader Compiler Version: XE031.05.13.02
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_PRIVATE_REDFOX64_MBR_RB1.05.01.01.003.020
Remote Branch : NONE
Reconstruct Branch : NOTHING
12-16 19:54:08.481 13572-13572/de.aintlarry.shotanalysis E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.aintlarry.shotanalysis, PID: 13572
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.setPreviewDisplay(android.view.SurfaceHolder)' on a null object reference
at de.aintlarry.shotanalysis.CameraPreview.surfaceCreated(CameraPreview.java:33)
at android.view.SurfaceView.updateWindow(SurfaceView.java:582)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2140)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1162)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6229)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:873)
at android.view.Choreographer.doCallbacks(Choreographer.java:676)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:859)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5781)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
12-16 19:54:10.562 13572-13572/de.aintlarry.shotanalysis D/Process: killProcess, pid=13572
12-16 19:54:10.571 13572-13572/de.aintlarry.shotanalysis D/Process: com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:113 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690

Antworten
  • Forum-Beiträge: 11.179

16.12.2015, 20:13:44 via Website

Sieht so aus als kann die Camera Instanz per Camera.open()
nicht geladen werden:
12-16 19:54:06.834 13572-13572/de.aintlarry.shotanalysis E/CAMERA: vorhanden
12-16 19:54:06.847 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:07.149 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:07.450 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:07.751 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:08.052 13572-13572/de.aintlarry.shotanalysis W/CameraBase: An error occurred while connecting to camera: 0
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis I/Camera2Mode: fail
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis E/MainActivity.java: Camera not available
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis E/MainActivity.java: CameraInstance: null
12-16 19:54:08.352 13572-13572/de.aintlarry.shotanalysis E/MainActivity.java: CameraInstance: null
12-16 19:54:08.430 13572-13621/de.aintlarry.shotanalysis I/Adreno: QUALCOMM build : 8e7809e, Ic2ca81

Könnte daran liegen, dass du nicht angibst welche Camera du haben willst ( Front/Back)
Schau mal ob das hilft:
http://stackoverflow.com/questions/14144838/sometime-camera-open-returns-null-or-sometime-its-working-fine
http://stackoverflow.com/questions/12054022/camera-open-returns-null

Bracuhst du das überhaupt in der APP?
Reicht dir da kein CameraIntent mit Bild als Return?

LG Pascal //It's not a bug, it's a feature. :) ;)

Ludy

Antworten
  • Forum-Beiträge: 607

16.12.2015, 20:35:33 via Website

Hallo Pascal,

habe es schon probiert mit camera.open(0); das funktioniert allerdings auch nicht.
Überall ist zu lesen, dass man camera.release(); einbauen soll. Um die Camera von anderen Apps zu trennen. Aber wo müsste ich das tun ?

Naja, zwingend notwendig ist es natürlich nicht. Ich finde, es ist aber eine wesentlich schönere Lösung als Intent.

Henrik

Antworten
  • Forum-Beiträge: 607

16.12.2015, 20:56:10 via Website

Die Seite hatte ich gestern auch schon gefunden, habe meinen Source nun wie folgt abgeändert:

public Camera getCameraInstance(){
    Camera c = null;
    try {
        releaseCameraAndPreview();
        c = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); // attempt to get a Camera instance
        Log.e(LOG, "CameraInstance: " + c + " RUNS");
    }
    catch (Exception e){
        Log.e(LOG, "Camera not available");
        Log.e(LOG, "CameraInstance: " + c);
    }
    Log.e(LOG, "CameraInstance: " + c);

    return c; // returns null if camera is unavailable

}

private void releaseCameraAndPreview() {
    if (mCamera != null) {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
}

Verändert hat sich aber nichts.

Ich verstehe das nicht, viele haben selbiges Problem, aber keine der Lösungen funktioniert in meinem Fall.
Der Sourcecode ist im Grund der von der Original AndroidDocumentaion von Google

Antworten
  • Forum-Beiträge: 11.179

17.12.2015, 16:34:38 via App

Da kann ich dir leider auch nicht weiterhelfen....

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 607

17.12.2015, 17:44:18 via Website

Hab inzwischen auf Stackoverflow eine Antwort bekommen.

Es könnte wohl daran liegen, dass bei API23 eine andere Berechtigung notwendig ist. Werde nachher mal einen Versuch auf meinem HTC One M7 (API 21) wagen. Wenn es da funktioniert, dann weiß ich bescheid. Wenn nicht, muss ich weiter suchen.

Ich halte euch auf dem laufenden.

Antworten
Ludy
  • Admin
  • Forum-Beiträge: 7.888

17.12.2015, 19:11:04 via Website

Hallo Henrik Martens,

ich befürchte du musst zwei Activitys schreiben eine kleiner API 21 und die andere ab API 21, hier nen Projekt ab API 21 https://github.com/googlesamples/android-Camera2Basic

Da ist dieser Code ganz super um zu Prüfen ob die Berechtigung für die API M gesetzt ist.

private void requestCameraPermission() {
    if (FragmentCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
        new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG);
    } else {
        FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
                REQUEST_CAMERA_PERMISSION);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode == REQUEST_CAMERA_PERMISSION) {
        if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
            ErrorDialog.newInstance(getString(R.string.request_permission))
                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);
        }
    } else {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Gruß Ludy (App Entwickler)

Mein Beitrag hat dir geholfen? Lass doch ein "Danke" da.☺

Lebensmittelwarnung-App

Download Samsung Firmware Tool

Meine Wunschliste

Telegram News Feed

Antworten
  • Forum-Beiträge: 607

17.12.2015, 21:25:09 via Website

Hallo Zusammen,

ich denke ich habe nun eine gute Lösung gefunden, mit nur einer Activity :)

Ich frage einfach bei App-Start ab, welches API-Level das Gerät hat. Bei 21 oder niedriger wird der Code einfach ausgeführt. Bei 23 (oder evtl irgendwann höher) wird nach der Permission gefragt, bzw. geprüft, ob der Nutzer diese schon bestätigt hat.

Funktioniert auf 21 und 23 wunderbar, soeben getestet.

Danke für eure tatkräftige Unterstützung.

Euer Henrik

Pascal P.Ludy

Antworten