2016-07-26 24 views
0

Ich habe zahlreiche Fragen zu fehlerhaften SurfaceView-Callbacks erhalten, aber keine hatte eine klare Lösung. Ich habe eine sehr einfache Layout-Datei, die eine SurfaceView, eine TextView und eine unbestimmte Fortschrittsanzeige hat. Meine ScanActivity registriert sich selbst als Callback zu der SurfaceView in ihrem Layout, aber nur surfaceDestroyed(SurfaceHolder holder) wird je nach meinen Logs aufgerufen. Aber die Aktivität hat eine Vorschau der Kamera, was seltsam ist, weil ich die SurfaceView als Kameravorschau in surfaceCreated anschloss und "Surface created". wird nie protokolliert, während "Oberfläche zerstört" ist. ist.SurfaceCreated (SurfaceHolder-Halter) wird nicht aufgerufen

scan.xml

<?xml version="1.0" encoding="utf-8"?> 

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <SurfaceView 
     android:id="@+id/camera_preview" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:background="@android:color/black" 
    /> 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="16dp" 
     android:layout_gravity="bottom|center_horizontal"> 

     <TextView 
      android:id="@+id/scan_instructions" 
      android:layout_width="wrap_content" 
      android:layout_height="fill_parent" 
      android:textSize="16sp" 
      android:gravity="center" 
      android:visibility="visible" 
      android:textColor="@android:color/primary_text_dark" 
      android:text="@string/scan_instructions" 
     /> 

     <ProgressBar 
      android:id="@+id/progress" 
      android:layout_width="32dp" 
      android:layout_height="32dp" 
      android:layout_margin="5dp" 
      android:indeterminate="true" 
     /> 

    </LinearLayout> 

</FrameLayout> 

ScanActivity.java

public class ScanActivity extends Activity implements SurfaceHolder.Callback { 

    private Camera camera; 
    private Scanner scanner; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.scan); 

     scanner = new Scanner(20) { 

      @Override 
      public void onPostExecute(String result) { 
       System.out.println("Read QR: " + result); 
       onQRScanned(result); 
      } 

     }; 

    } 

    /** 
    * Registers this class as the callback for the image surface in the layout XML. 
    */ 
    @Override 
    public void onStart() { 

     super.onStart(); 
     ((SurfaceView) findViewById(R.id.camera_preview)).getHolder().addCallback(this); 

    } 


    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     System.out.println("Surface created."); 
     surfaceDestroyed(holder); 

     try { 

      // Open the camera. 
      camera = Camera.open(); 
      camera.setPreviewDisplay(holder); 
      camera.setPreviewCallback(scanner); 
      System.out.println("Connected QR scan task."); 

     } catch (NullPointerException e) { 

      // Didn't find a camera to open. 
      e.printStackTrace(); 
      surfaceDestroyed(holder); 
      return; 

     } catch (IOException e) { 

      // Camera preview setup failed. 
      e.printStackTrace(); 
      surfaceDestroyed(holder); 
      return; 

     } catch (RuntimeException e) { 

      // The app was denied permission to camera services. 
      e.printStackTrace(); 
      surfaceDestroyed(holder); 
      return; 

     } 

     // Set auto-focus mode 
     Parameters params = camera.getParameters(); 
     List<String> modes = params.getSupportedFocusModes(); 
     if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) 
      params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
     else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) 
      params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); 
     else if (modes.contains(Parameters.FOCUS_MODE_AUTO)) { 
      params.setFocusMode(Parameters.FOCUS_MODE_AUTO); 
     } 
     camera.setParameters(params); 
    } 

    /** 
    * If the preview surface is altered for some reason, fixes it and refreshes the preview. 
    */ 
    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

     System.out.println("Surface changed."); 

     if (camera == null) 
      return; 

     camera.setDisplayOrientation(90); 
     camera.startPreview(); 

    } 

    /** 
    * When the activity is closed, release the camera. 
    */ 
    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 

     System.out.println("Surface destroyed."); 

     if (camera == null) 
      return; 

     camera.stopPreview(); 
     camera.setPreviewCallback(null); 
     camera.release(); 
     camera = null; 
     scanner.cancel(true); 

    } 

    /** 
    * Called when a QR code is successfully read from the preview. 
    * @param content The text encoded in the QR. 
    */ 
    private void onQRScanned(String content) { 

     if (content != null) { 

      getIntent().putExtra("qr_content", content); 
      setResult(RESULT_OK, getIntent()); 
      finish(); 

     } else { 

      setResult(RESULT_CANCELED); 
      finish(); 

     } 

    } 

} 
+1

Sie rufen 'SurfaceDestroyed (Holder);' in 'SurfaceCreated()' –

+0

Hört das SurfaceCreated (Halter)? –

+1

Ja, wenn es erstellt wird, zerstörst du es mit Gewalt. –

Antwort

1

ich Ihren Code und surfaceCreated() versucht haben, wurde wie erwartet genannt. Sie überprüfen Ihren Logcat falsch. Versuchen Sie, Log.d("MainActivity", "Surface created."); anstelle von System.out.println zu verwenden. Lernen Sie auch how to use debugger.