2013-10-04 69 views
19

我試圖創建一個研究簡單的攝像頭應用程序。 我閱讀Android Camera Official Document,然後開始編碼。 所以我做了一些步驟,以得到它的工作攝像頭:setDisplayOrientation功能不工作了三星Galaxy ACE採用Android 2.3.6

相機功能所需1.添加權限的應用程序。

2.locked我的活動只肖像模式。

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

3.增加了幾個相機回調讓我的相機工作。

  • SurfaceHolder.Callback,
  • Camera.PreviewCallback
  • AutoFocusCallback
  • ShutterCallback
  • PictureCallback對RAW圖像數據
  • PictureCallback爲JPG圖像數據

4.In surfaceChanged方法我正在自定義相機設置。 到目前爲止我得到了工作這對於幾乎所有的Android設備

  • LG
  • 香料
  • 三星
  • HTC
  • Micromax的
  • 索尼
  • 摩托羅拉
  • 谷歌Nexus系列。

然後我就三星Galaxy ACE測試了Android 2.3.6版本和 發現攝像機畫面預覽旋轉爲橫向模式。

所以把日誌貓/破發點,我才知道,下面的方法是不能用於該特定型號後

//This method is not working for Samsung Galaxy ACE 
camera.setDisplayOrientation(90); 
//or 
parameters.set("orientation", "portrait"); 
//or 
parameters.setRotation(90); 

注:我搜遍了一堆對谷歌的解決方案和SO以及但至今沒有得到任何運氣在這個

供您參考我的示例代碼低於

@Override 
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 
     Log.v(TAG, "surfaceChanged get called"); 

     if (previewing) { 
      camera.stopPreview(); 
      previewing = false; 
     } 

     if (camera != null) { 
      try { 
       Camera.Parameters parameters = camera.getParameters(); 
       List<Size> sizes = parameters.getSupportedPictureSizes(); 

       Camera.Size result = null; 
       for (int i = 0; i < sizes.size(); i++) { 
        result = (Size) sizes.get(i); 
        Log.i("PictureSize", "Supported Size. Width: " 
          + result.width + "height : " + result.height); 

        if (result.width == 640) { 
         parameters.setPreviewSize(result.width, result.height);// 640*480 
         parameters.setPictureSize(result.width, result.height); 
        } else { 

        } 
       } 


       //**************************************************************// 

       /* 
       * Here is the logic I have added to Manage Camera Display Orientation 
       * It checks Current Orientation and SDK and then rotate display to make it Portrait view. 
       */ 
       int currentSDKVersion = android.os.Build.VERSION.SDK_INT; 
       Log.d(TAG, "currentVersion " + currentSDKVersion); 

       if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
        if (currentSDKVersion != 7) { 

         camera.setDisplayOrientation(90); 
         parameters.setRotation(90); 
        } else { 
          parameters.setRotation(90); 

         /* 
         * params.set("orientation", "portrait"); 
         * params.set("rotation",90); 
         */ 
        } 
       } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 
        if (currentSDKVersion != 7) { 

         camera.setDisplayOrientation(0); 
        } else { 

         parameters.set("orientation", "landscape"); 
         parameters.set("rotation", 90); 

        } 
       } 


       //**************************************************************// 

       camera.setParameters(parameters); 
       camera.setPreviewDisplay(surfaceHolder); 
       camera.startPreview(); 
       camera.autoFocus(myAutoFocusCallback); 
       camera.setOneShotPreviewCallback(cameraPreviewCallback); 
       previewing = true; 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

我的相機活動(MainActivity.java)的完整代碼:

public class MainActivity extends Activity implements SurfaceHolder.Callback, 
     OnClickListener { 

    public static final String TAG = "CameraActivity"; 
    private Context context = null; 
    Camera camera = null; 
    private SurfaceView surfaceView = null; 
    private SurfaceHolder surfaceHolder = null; 
    boolean previewing = false; 
    private LayoutInflater controlInflater = null; 
    private Button buttonTakePicture = null; 
    //private TextView textViewResultInfo = null; 

    @SuppressWarnings("deprecation") 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     Log.v(TAG, "onCreate get called"); 

     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

     //textViewResultInfo = (TextView) findViewById(R.id.textViewResultInfo); 
     context = this; 

     getWindow().setFormat(PixelFormat.UNKNOWN); 
     surfaceView = (SurfaceView) findViewById(R.id.surfaceview); 
     surfaceHolder = surfaceView.getHolder(); 
     surfaceHolder.addCallback(this); 
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     controlInflater = LayoutInflater.from(getBaseContext()); 
     View viewControl = controlInflater.inflate(R.layout.control, null); 
     LayoutParams layoutParamsControl = new LayoutParams(
       LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 
     this.addContentView(viewControl, layoutParamsControl); 

     buttonTakePicture = (Button) findViewById(R.id.takepicture); 
     buttonTakePicture.setOnClickListener(this); 

    } 

    @Override 
    public void surfaceCreated(SurfaceHolder arg0) { 

     Log.v(TAG, "surfaceCreated get called"); 
     camera = Camera.open(); 

     if (camera != null) { 
      try { 
       camera.setPreviewDisplay(surfaceHolder); 
       camera.startPreview(); 
       previewing = true; 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

    @Override 
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 
     Log.v(TAG, "surfaceChanged get called"); 

     if (previewing) { 
      camera.stopPreview(); 
      previewing = false; 
     } 

     if (camera != null) { 
      try { 

       //new MainActivity().setCameraDisplayOrientation(); 

       Camera.Parameters parameters = camera.getParameters(); 
       // List<String> focusModes = 
       // parameters.getSupportedFocusModes(); 
       // if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) 
       // { 
       // parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
       // } 

       List<Size> sizes = parameters.getSupportedPictureSizes(); 

       Camera.Size result = null; 
       for (int i = 0; i < sizes.size(); i++) { 
        result = (Size) sizes.get(i); 
        Log.i("PictureSize", "Supported Size. Width: " 
          + result.width + "height : " + result.height); 

        if (result.width == 640) { 
         parameters.setPreviewSize(result.width, result.height);// 640*480 
         parameters.setPictureSize(result.width, result.height); 
        } else { 

        } 
       } 


       //**************************************************************// 

       Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
       int rotation = display.getRotation(); 
       Log.v(TAG, "Current Device Orientation is ="+rotation); 

       /* 
       * Here is the logic I have added to Manage Camera Display Orientation 
       * It checks Current Orientation and SDK and then rotate display to make it Portrait view. 
       */ 
       int currentSDKVersion = android.os.Build.VERSION.SDK_INT; 
       Log.d(TAG, "currentVersion " + currentSDKVersion); 

       if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
        if (currentSDKVersion != 7) { 
         Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion 
           + "rotate 90"); 
         camera.setDisplayOrientation(90); 
         parameters.setRotation(90); 
        } else { 
         Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion 
           + "rotate 90"); 
         parameters.setRotation(90); 

         /* 
         * params.set("orientation", "portrait"); 
         * params.set("rotation",90); 
         */ 
        } 
       } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 
        if (currentSDKVersion != 7) { 
         Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion 
           + "rotate 90"); 

         camera.setDisplayOrientation(0); 
        } else { 

         Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion 
           + "rotate 90"); 

         parameters.set("orientation", "landscape"); 
         parameters.set("rotation", 90); 

        } 
       } 


       //**************************************************************// 


       camera.setParameters(parameters); 
       camera.setPreviewDisplay(surfaceHolder); 
       camera.startPreview(); 
       camera.autoFocus(myAutoFocusCallback); 
       camera.setOneShotPreviewCallback(cameraPreviewCallback); 
       previewing = true; 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder arg0) { 
     Log.v(TAG, "surfaceDestroyed get called"); 
     camera.stopPreview(); 
     camera.release(); 
     camera = null; 
     previewing = false; 

    } 


    public void setCameraDisplayOrientation() 
    {   
     Log.v(TAG, "setCameraDisplayOrientation get called"); 

     if (camera == null) 
     { 
      Log.d(TAG,"setCameraDisplayOrientation - camera null"); 
      return;    
     } 

     Camera.CameraInfo info = new Camera.CameraInfo(); 
     Camera.getCameraInfo(1, info); 

     WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
     int rotation = winManager.getDefaultDisplay().getRotation(); 

     int degrees = 0; 

     switch (rotation) 
     { 
      case Surface.ROTATION_0: degrees = 0; break; 
      case Surface.ROTATION_90: degrees = 90; break; 
      case Surface.ROTATION_180: degrees = 180; break; 
      case Surface.ROTATION_270: degrees = 270; break; 
     } 

     int result; 
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) 
     { 
      result = (info.orientation + degrees) % 360; 
      result = (360 - result) % 360; // compensate the mirror 
     } else { // back-facing 
      result = (info.orientation - degrees + 360) % 360; 
     } 
     camera.setDisplayOrientation(result); 
    } 


    @Override 
    public void onClick(View v) { 
     Log.v(TAG, "onClick get called"); 

     if (v == buttonTakePicture) { 
      camera.takePicture(myShutterCallback, myPictureCallback_RAW, 
        myPictureCallback_JPG); 
     } 

    } 

    private Camera.PreviewCallback cameraPreviewCallback = new Camera.PreviewCallback() { 
     @Override 
     public void onPreviewFrame(byte[] data, Camera camera) { 
      Log.i(TAG, "onPreviewFrame size=" + data.length); 
     } 
    }; 

    AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback() { 

     @Override 
     public void onAutoFocus(boolean arg0, Camera arg1) { 
      Log.v(TAG, "onAutoFocus get called"); 
      buttonTakePicture.setEnabled(true); 
     } 
    }; 

    ShutterCallback myShutterCallback = new ShutterCallback() { 

     @Override 
     public void onShutter() { 
      Log.v(TAG, "onShutter get called"); 
     } 
    }; 

    PictureCallback myPictureCallback_RAW = new PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] arg0, Camera arg1) { 
      Log.v(TAG, "onPictureTaken-RAW get called"); 

     } 
    }; 

    public static Bitmap RotateBitmap(Bitmap source, float angle) { 
     Matrix matrix = new Matrix(); 
     matrix.postRotate(angle); 
     return Bitmap.createBitmap(source, 0, 0, source.getWidth(), 
       source.getHeight(), matrix, true); 
    } 

    PictureCallback myPictureCallback_JPG = new PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] arg0, Camera arg1) { 
      Bitmap rawImage = BitmapFactory.decodeByteArray(arg0, 0, 
        arg0.length); 

      if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
       Log.v(TAG, "##### ORIENTATION_PORTRAIT ####"); 

       rawImage = MainActivity.RotateBitmap(rawImage, 90); 

       ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
       rawImage.compress(Bitmap.CompressFormat.JPEG, 100, stream); 
       arg0 = stream.toByteArray(); 

      } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 
       Log.v(TAG, "##### ORIENTATION_LANDSCAPE #####"); 

      } 

      Intent intent = new Intent(MainActivity.this, ResultActivity.class); 
      intent.putExtra("picture", arg0); 
      startActivity(intent); 

      Log.v(TAG, "onPictureTaken-JPG get called"); 

     } 
    }; 

    /** 
    * Get the size in bitmap. 
    * 
    * @param bitmap 
    * @return size in bytes 
    */ 
    @TargetApi(12) 
    public static int getBitmapSize(Bitmap bitmap) { 
     if (MainActivity.hasHoneycombMR1()) { 
      return bitmap.getByteCount(); 
     } 
     // Pre HC-MR1 
     return bitmap.getRowBytes() * bitmap.getHeight(); 
    } 

    public static boolean hasHoneycombMR1() { 
     return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1; 
    } 

} 

編輯:我已經發表的評論上Developer forum,但沒有任何反應。

請!有人對這個問題有任何想法。

我真的很感激任何形式的建議。

+0

爲什麼你不使用manifest屬性'android:screenOrientation =「portrait」'的任何特定原因?你可能想嘗試一下,儘管我不會指望它有任何改變。此外,您是否嘗試在「裸露」項目中重現該問題 - 僅僅是爲了排除它實際上是設備特定的問題,而不是潛在的實施錯誤? –

+0

@MH。親!感謝您的評論。上面的清單標籤,我已經添加,這是爲應用程序屏幕沒有相機預覽屏幕,btw標籤工作正常,所以應用程序屏幕始終在肖像模式,但我想旋轉相機預覽得到旋轉。即使我手動嘗試Java反射旋轉,也檢查了三星開發者網站和谷歌Android開發者的所有問題,但沒有運氣。 – swiftBoy

+0

嘿RDC,你在最後弄明白了嗎?看起來好像沒有答案真的可以100%正常工作,例如:一旦嘗試了大部分答案,我都可以讓三星手機和仿真器工作,但Nexus例如失敗。任何想法?謝謝! –

回答

8

當我與原來的Galaxy Tab運行2.2.1類似的問題,我可以通過以下操作來解決它:

Camera.Parameters parameters = camera.getParameters(); 
parameters.set("orientation", "portrait"); 
parameters.setRotation(90); 
camera.setParameters(parameters); 

但是,它看起來像你可能已經嘗試確切的組合,因爲你有相同的(但註釋掉)以上的代碼。然而,您現在擁有代碼的方式,由於API級別(10),Ace將繞過您已經註釋過的代碼。具體試試這個塊中:

if (currentSDKVersion != 7) { } 

讓我知道,如果它的工作原理,請。謝謝!

+1

我根據您的評論更新了內容,但結果仍然保持不變,即橫向排列。 – swiftBoy

+2

感謝您的更新;這是完全可能的,這是一個特定的手機的錯誤,並且沒有辦法解決它。這不會是第一次特定的設備有一個獨特的錯誤。而且,在這一點上它已經很老了;如果這在Ace中不起作用,它是一個破壞者嗎? –

+0

方法getParameters()是未定義的類型相機 – Prasad

0

我也在尋找一個解決方案的小時。它真的很瘋狂。 我的解決方案是在橫向模式下(在我的肖像應用程序中)使用相機預覽,並掩蓋不需要的預覽部分。我通過用一些視圖覆蓋我的全屏預覽的上下部分來完成此操作。因爲你必須裁剪你從照相機得到的照片,那麼結果不那麼令人滿意。對於我的應用程序,這不是問題。

我現在完全滿意我的解決方案 - 用戶沒有看到任何區別;

+0

我完全同意你,並尊重你的話..但我只限於肖像模式,因爲我需要發送結果圖像進行圖像識別所以**如果我鎖定到風景 - >這將需要旋轉,調整圖像,發送壓縮圖像,而我只有幾毫秒的整個過程,也影響一些滑動動畫,因爲下一個屏幕是肖像鎖定。因此,橫向 - >縱向幻燈片不起作用。**最終,我必須不惜任何代價進入肖像模式。以及感謝您寶貴的時間。 – swiftBoy

0

我已經寫了一些代碼,這是majorly從斑馬線項目適應處理相機:http://code.google.com/p/zxing/

你可以嘗試使用這些。如果你正在嘗試使用這個,我會建議通過這個解決方案stackoverflow question

這可能不是你的問題的完美解決方案,但我已經跑過這個問題,並已決定使用Zxing。

相關問題