2013-07-24 4 views
5

내 프로젝트에 QR 스캐너가 있어야합니다. 이 작업을 수행하는 데 ZBar를 사용합니다. 주로 나는 ZBar git 예제에서 주어진 예제 코드에 아주 작은 변화를 주었다. 검색 결과를 브라우저 (URL 인 경우) 또는 대화 상자 (정상적인 정보 인 경우)에 표시해야합니다.안드로이드가 장착 된 Zbar : 스캐너 카메라 뷰포트는 브라우저에 URL을 표시 한 후 비활성 상태 및 검은 색으로 남아 있습니다.

브라우저에서 qr 코드를 검색 한 후에 URL을 표시하려고 시도하는 경우를 제외하고 모든 사항이 내 코드와 잘 작동합니다. 브라우저에서 내 앱으로 돌아 왔을 때 카메라 뷰포트가 검은 색으로 변하고 비활성 상태로 남아 있습니다. 다른 qr 코드를 스캔하기 위해 카메라를 다시 작동 시키려고했으나 실패했습니다. 내 onResume() 함수에서 카메라를 다시 열려고했지만 오류가 발생하여 앱에서 강제로 종료되었습니다. 그 문제를 도와주세요.

package com.myapp; 
    import net.sourceforge.zbar.Config; 
    import net.sourceforge.zbar.Image; 
    import net.sourceforge.zbar.ImageScanner; 
    import net.sourceforge.zbar.Symbol; 
    import net.sourceforge.zbar.SymbolSet; 
    import android.app.Activity; 
    import android.app.AlertDialog; 
    import android.content.DialogInterface; 
    import android.content.Intent; 
    import android.content.pm.ActivityInfo; 
    import android.hardware.Camera; 
    import android.hardware.Camera.AutoFocusCallback; 
    import android.hardware.Camera.PreviewCallback; 
    import android.hardware.Camera.Size; 
    import android.net.Uri; 
    import android.os.Bundle; 
    import android.os.Handler; 
    import android.webkit.URLUtil; 
    import android.widget.FrameLayout; 

    import com.myapp.CameraPreview; 
    /* Import ZBar Class files */ 

    public class QRScannerActivity extends Activity 
    { 
     private Camera mCamera; 
     private CameraPreview mPreview; 
     private Handler autoFocusHandler; 

     ImageScanner scanner; 

     private boolean barcodeScanned = false; 
     private boolean previewing = true; 

     static { 
      System.loadLibrary("iconv"); 
     } 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 

      super.onCreate(savedInstanceState); 

      setContentView(R.layout.qr_scanner_main); 

      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

      autoFocusHandler = new Handler(); 
      mCamera = getCameraInstance(); 

      /* Instance barcode scanner */ 
      scanner = new ImageScanner(); 
      scanner.setConfig(0, Config.X_DENSITY, 3); 
      scanner.setConfig(0, Config.Y_DENSITY, 3); 

      mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB); 
      FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview); 
      preview.addView(mPreview); 
     } 

     @Override 
     protected void onPause() { 
      super.onPause(); 
      releaseCamera(); 
      //finish(); 
     } 

     /** A safe way to get an instance of the Camera object. */ 
     public static Camera getCameraInstance(){ 
      Camera c = null; 
      try { 
       c = Camera.open(); 
      } catch (Exception e){ 
      } 
      return c; 
     } 

     private void releaseCamera() { 
      //Toast.makeText(QRScannerActivity.this, "Paused State", Toast.LENGTH_SHORT).show(); 
      if (mCamera != null) { 
       previewing = false; 
       mCamera.setPreviewCallback(null); 
       mPreview.getHolder().removeCallback(mPreview); 
       mCamera.release(); 
       mCamera = null; 
      } 

     } 

     private Runnable doAutoFocus = new Runnable() { 
       public void run() { 
        if (previewing) 
         mCamera.autoFocus(autoFocusCB); 
       } 
      }; 

     PreviewCallback previewCb = new PreviewCallback() { 
       public void onPreviewFrame(byte[] data, Camera camera) { 
        Camera.Parameters parameters = camera.getParameters(); 
        Size size = parameters.getPreviewSize(); 

        Image barcode = new Image(size.width, size.height, "Y800"); 
        barcode.setData(data); 

        int result = scanner.scanImage(barcode); 
        String QRScannerResult; 

        if (result != 0) { 
         previewing = false; 
         mCamera.setPreviewCallback(null); 
         mCamera.stopPreview(); 

         SymbolSet syms = scanner.getResults(); 
         for (Symbol sym : syms) { 
          QRScannerResult = sym.getData(); 
          showResultAction(QRScannerResult); 
          barcodeScanned = true; 

         } 
        } 
       } 
      }; 

     // Mimic continuous auto-focusing 
     AutoFocusCallback autoFocusCB = new AutoFocusCallback() { 
       public void onAutoFocus(boolean success, Camera camera) { 
        autoFocusHandler.postDelayed(doAutoFocus, 1000); 
       } 
      }; 

     private void showResultAction(String QRScannerResult){ 
       if (URLUtil.isValidUrl(QRScannerResult)) { 

        if (barcodeScanned) { 
         barcodeScanned = false; 
         mCamera.setPreviewCallback(previewCb); 
         mCamera.startPreview(); 
         previewing = true; 
         mCamera.autoFocus(autoFocusCB); 
        } 

        Intent i = new Intent(Intent.ACTION_VIEW); 
        i.setData(Uri.parse(QRScannerResult)); 
        startActivity(i); 

        }else { 
         new AlertDialog.Builder(this) 
         .setTitle("QR Data") 
         .setMessage(QRScannerResult) 
         .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int which) { 
           if (barcodeScanned) { 
            barcodeScanned = false; 
            mCamera.setPreviewCallback(previewCb); 
            mCamera.startPreview(); 
            previewing = true; 
            mCamera.autoFocus(autoFocusCB); 
           } 
          } 
         }) 
         .show(); 
        } 

     } 
    } 

미리 감사드립니다. Sakib

답변

9

마침내 필자는 코드의 문제점을 발견하고 솔루션을 얻었습니다. 내 onResume() 방법으로 카메라를 다시 열려고하면 부분을 놓쳤습니다. onResume()에 새 카메라를 만들거나 열면 FrameLayout에 이전 카메라가 남아 있습니다. 그래서 내가하는 일은 onPause() 메서드에서 FrameLayout에서 이전 카메라를 제거한 다음 onResume() 메서드에서 모든 것을 다시 생성하는 것입니다. 그게 내 문제를 해결하고 지금은 어떤 오류없이 멋지게 작동합니다. 이 수정 프로그램은 내 onPause()onResume() 메서드입니다. 희망이 미래에 누군가를 도울 수 있습니다.

public void onPause() { 
     super.onPause(); 
     releaseCamera(); 
     FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview); 
     preview.removeView(mPreview); 
    } 

    public void onResume(){ 
     super.onResume(); 

     try { 
      if(mCamera==null){ 

      //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
      autoFocusHandler = new Handler(); 
      mCamera = getCameraInstance(); 
      this.getWindowManager().getDefaultDisplay().getRotation(); 

      scanner = new ImageScanner(); 
      scanner.setConfig(0, Config.X_DENSITY, 3); 
      scanner.setConfig(0, Config.Y_DENSITY, 3); 

      mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB); 
      FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview); 
      preview.addView(mPreview); 
      } 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 

     } 
    } 

    /** A safe way to get an instance of the Camera object. */ 
    public static Camera getCameraInstance(){ 
     Camera c = null; 
     try { 
      c = Camera.open(); 
     } catch (Exception e){ 
     } 
     return c; 
    } 

    private void releaseCamera() { 
     //Toast.makeText(QRScannerActivity.this, "Paused State", Toast.LENGTH_SHORT).show(); 
     if (mCamera != null) { 
      previewing = false; 
      mCamera.setPreviewCallback(null); 
      mPreview.getHolder().removeCallback(mPreview); 
      mCamera.release(); 
      mCamera = null; 
      mPreview= null; 
     } 

    } 

감사합니다, Sakib

+1

감사합니다. 정말 도움이됩니다. – Drx

+0

내 시간을 절약 해 주셨습니다 :) ur 코드를 공유해 주셔서 감사합니다. –