2016-07-26 3 views
0

Я видел многочисленные вопросы о неисправных обратных вызовах SurfaceView, но ни у кого не было четкого решения. У меня очень простой файл макета, который имеет SurfaceView, TextView и неопределенный индикатор прогресса. Мой ScanActivity регистрируется как обратный вызов SurfaceView в его макете, но только surfaceDestroyed(SurfaceHolder holder) когда-либо называется, согласно моим журналам. Но активность успешно просматривает камеру, что странно, потому что я привязал SurfaceView как предварительный просмотр камеры в surfaceCreated и «Surface created». никогда не регистрируется, пока «поверхность разрушена». является.surfaceCreated (держатель поверхностного держателя) не называется

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

Вы вызываете 'surfaceDestroyed (держатель);' in 'surfaceCreated()' –

+0

Означает ли это, что stop surfaceCreated (holder)? –

+1

Да, так как он создается, вы насильно уничтожаете его. –

ответ

1

Я попробовал ваш код и surfaceCreated() был назван, как и ожидалось. Вы неправильно проверяете свой логарифм. Попробуйте использовать Log.d("MainActivity", "Surface created."); вместо System.out.println. Также изучите how to use debugger.

Смежные вопросы