Камера: функция setDisplayOrientation не работает для Samsung Galaxy ACE с Android 2.3.6

Я пытался создать простую камеру для исследований. Я прочитал официальный документ камеры Android, а затем начал кодирование. Поэтому я сделал несколько шагов, чтобы заставить его работать

1.Добавлены необходимые разрешения для функции камеры в приложении.

2. заблокировал мою активность только в режиме ПОРТРЕТ.

setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

3.Добавлено несколько обратных вызовов камеры, чтобы заставить мою камеру работать.

  • SurfaceHolder.Callback,
  • Camera.PreviewCallback
  • AutoFocusCallback
  • ShutterCallback
  • PictureCallback для данных изображения RAW
  • PictureCallback для данных изображения JPG

4. В методе surfaceChanged я настраиваю настройки камеры. И до сих пор я работал над этим почти для всех устройств Android

  • LG
  • пряность
  • Samsung
  • HTC
  • Micromax
  • Sony
  • Motorola
  • Google Nexus.

Но затем я протестировал на Samsung 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); 

Примечание. Я охотился на множество решений по Google и SO, но пока не получилось удачи в этом

  • Иссус сообщил здесь
  • Ориентация просмотра поверхности андроида
  • Android-порт заблокирован Просмотр камеры
  • Android – предварительный просмотр камеры в боковом направлении
  • Вращение камеры Android
  • Android: просмотр камеры повернут
  • Как правильно настроить ориентацию камеры Android?

Для вашей справки Мой примерный код ниже

 @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; } } 

Редактировать : я опубликовал комментарий на форуме разработчиков, но ответа нет.

Пожалуйста!! У кого-то есть идея относительно этой проблемы.

Я был бы очень признателен за любое предложение.

Когда у меня была аналогичная проблема с оригинальной вкладкой Galaxy Tab 2.2.1, я смог ее решить, выполнив следующие действия:

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

Тем не менее, похоже, что вы уже пробовали эту точную комбинацию, учитывая, что у вас есть идентичный (но прокомментированный) код выше. Однако, как у вас есть код прямо сейчас, Ace собирается обойти, где у вас есть код с комментариями из-за его уровня API (10). Попробуйте это прямо внутри этого блока:

 if (currentSDKVersion != 7) { } 

И дайте мне знать, если это сработает, пожалуйста. Благодаря!

Я тоже искал решение часами. Это действительно сумасшедший. Мое решение состояло в том, чтобы просто использовать предварительный просмотр камеры в ландшафтном режиме (в моем приложении для портрета) и замаскировать части предварительного просмотра, которые мне не нужны. Я сделал это, наложив верхний и нижний части моего полноэкранного предварительного просмотра на некоторые виды. Из-за этого вы должны обрезать фотографию, которую вы получаете с камеры, тогда КОТОРЫЕ РЕЗУЛЬТАТЫ В МЕНЬШЕЙ РЕЗОЛЮЦИИ. Для моего приложения это не проблема.

Теперь я полностью доволен своим решением – пользователи не видят разницы;

Я обработал камеру, написав код, который был в основном адаптирован из проекта ZXing: http://code.google.com/p/zxing/

Вы можете попробовать их использовать. Если вы пытаетесь использовать это, я бы порекомендовал пройти через решение этого вопроса stackoverflow

Возможно, это не идеальное решение вашего вопроса, но я столкнулся с этой проблемой и решил использовать Zxing.