I was trying to create a simple camera application for research. I Read Android Camera Official Document and then started coding. so I did some steps to get it work
1.Added required permissions for Camera feature in app.
2.locked my activity to PORTRAIT mode only.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
3.Added several camera callbacks to get my camera works.
4.In surfaceChanged method I am customizing camera settings. and so far I got working this for almost all android devices
But then I tested on Samsung Galaxy ACE with Android Version 2.3.6 and found Camera Display Preview is Rotated to landscape mode.
So after putting log-cat/break points I come to know that below methods are not working for this particular model
//This method is not working for Samsung Galaxy ACE
camera.setDisplayOrientation(90);
//or
parameters.set("orientation", "portrait");
//or
parameters.setRotation(90);
Note: I Hunted bunch of solutions over Google and SO as well but so far didn't get any luck in this
For your reference My sample code is below
@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();
}
}
}
My Camera Activity (MainActivity.java) Full code is:
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;
}
}
Edit : I have posted Comment on Developer forum but no response.
Please!! Someone have any Idea regarding this problem.
I would really appreciate for any kind of suggestion.
When I had a similar problem with the original Galaxy Tab running 2.2.1, I was able to solve it by doing the following:
Camera.Parameters parameters = camera.getParameters();
parameters.set("orientation", "portrait");
parameters.setRotation(90);
camera.setParameters(parameters);
However, it looks like you may have already tried that exact combination, given that you have identical (but commented out) code above. However, the way you have the code right now, the Ace is going to bypass where you have that commented code because of it's API level (10). Try it specifically inside this block:
if (currentSDKVersion != 7) { }
And let me know if it works, please. Thanks!