Custom Camera Preview Issue (Stretch) - java

I'm having a problem with my camera app.
My app has:
1) a CameraActivity.class and
2) a CameraPreview.class.
CameraPreview implement a surfaceView where it's called from CameraActivity for the actual preview. (Also in CameraActivity I have the parameters)
Now the problem: When the preview is starting the preview is stretched.
I tried a lot of things (so many that I cannot recall)
I need someone to tell me what to write and where. Thanks in advance.
Here is the CameraActivity(Not all the code but the important I think)
private PictureCallback mPicture = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// Replacing the button after a photho was taken.
flBtnContainer.setVisibility(View.GONE);
ibRetake.setVisibility(View.VISIBLE);
ibUse.setVisibility(View.VISIBLE);
// File name of the image that we just took.
fileName = "IMG_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()).toString() + ".jpg";
// Creating the directory where to save the image. Sadly in older
// version of Android we can not get the Media catalog name
File mkDir = new File(sdRoot, dir);
mkDir.mkdirs();
// Main file where to save the data that we recive from the camera
File pictureFile = new File(sdRoot, dir + fileName);
try {
FileOutputStream purge = new FileOutputStream(pictureFile);
purge.write(data);
purge.close();
} catch (FileNotFoundException e) {
Log.d("DG_DEBUG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage());
}
// Adding Exif data for the orientation. For some strange reason the
// ExifInterface class takes a string instead of a file.
try {
exif = new ExifInterface("/sdcard/" + dir + fileName);
exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation);
exif.saveAttributes();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(CameraActivity.this, PicturePreview.class);
Bundle extras = new Bundle();
extras.putString("ImagePath", String.valueOf(pictureFile));
intent.putExtras(extras);
startActivity(intent);
//SendBroadcasts let's us instantly update the SD card with our image
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+Environment.getExternalStorageDirectory())));
}
};
private void createCamera() {
// Create an instance of Camera
mCamera = getCameraInstance();
// Setting the right parameters in the camera
Camera.Parameters params = mCamera.getParameters();
params.setRotation(90);
mCamera.setParameters(params);
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview, 0);
}
#Override
protected void onResume() {
super.onResume();
// Test if there is a camera on the device and if the SD card is
// mounted.
if (!checkCameraHardware(this)) {
Intent i = new Intent(this, NoCamera.class);
startActivity(i);
finish();
} else if (!checkSDCard()) {
Intent i = new Intent(this, NoSDCard.class);
startActivity(i);
finish();
}
// Creating the camera
createCamera();
// Register this class as a listener for the accelerometer sensor
////sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
// release the camera immediately on pause event
releaseCamera();
// removing the inserted view - so when we come back to the app we
// won't have the views on top of each other.
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.removeViewAt(0);
}
And here is the CameraPreview.class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
boolean isPreviewRunning = true;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.setFixedSize(100, 100);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the
// preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
Log.d("DG_DEBUG", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
if (isPreviewRunning){
return;
}
isPreviewRunning = true;
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d("DG_DEBUG", "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
}
Can someone tell what am I missing? If possible I can chat in Facebook or something for faster resolve of my problem..
Update: #LikeWhiteOnRice's solution.
Here is my original code
enter image description here
Here is with LikeWhiteOnRice's code:
enter image description here
Any thoughts?

I added the code below to my camera preview class and it works for most devices. Just so you are aware, the camera library in Android is horrible and a huge pain to work with.
Put this function in your CameraPreview class:
private Camera.Size getOptimalSize(List<Camera.Size> sizes, int h, int w) {
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) w/h;
if (sizes == null) {
return null;
}
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
In your surefaceCreated function, add this before you start your preview:
Camera.Parameters cameraParameters = mCamera.getParameters();
List<Camera.Size> previewSizes = cameraParameters.getSupportedPreviewSizes();
Camera.Size optimalPreviewSize = getOptimalSize(previewSizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
cameraParameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);
mCamera.setParameters(cameraParameters);
Edit: Also, I'm not sure if you want
mHolder.setFixedSize(100, 100);
in your constructor.

Related

Wallpaper setbitmap displays black screen android

When using serBitmap through WallpaperManager ie., wallpaperManager.setBitmap(wallpaperBitmap); I am getting black screen when new wallpaper been set. How to remove the black screen when transition from old wallpaper to new wallpaper?
From where this black screen been displayed in aosp 10?
Below is the code snippet:
setUserWallpaper(this,"test");
private void setUserWallPaper(final Context context, final String userName) {
setUserWallpaperRunnable =
new Runnable() {
#Override
public void run() {
Log.i(TAG, "setUserWallPaper() run");
InputStream in = null;
OutputStream out = null;
try {
in = new BufferedInputStream(
context.getContentResolver()
.openInputStream(
Uri.parse(
"content://test.app.personalization.provider/" +
"wall_paper" +
"?user=" +
userName +
"&encryption=false"))
);
Bitmap wallpaperBitmap = BitmapFactory.decodeStream(in);
if(wallpaperBitmap != null){
WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
wallpaperManager.setBitmap(wallpaperBitmap);
} else {
Log.i(TAG, "user wallpaper is null.");
}
Log.i(TAG, "setUserWallPaper() end");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
if(out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
sUserCustomizeWorker.post(setUserWallpaperRunnable);
}
I know this bug.
Problem: Bitmap is too big for wallpaper so you have to rescale the bitmap.
Rule: bitmap width < device width * 2 and bitmap height < device height * 2.

Simple application of photo on Android Studio using Android tutorial of Camera

I want to create an application to take a picture. I followed the Camera tutorial, I tried 3 times but unable to make it work.I added a button to take a picture.But the app is not working properly.Please help me out.Here is my code:
// CAMERA VIEW displays the picture in a FrameLayout
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context, Camera camera){
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(0);
//get the holder and set this class as the callback, so we can get camera data here
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try{
//when the surface is created, we can set the camera to draw images in this surfaceholder
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
//before changing the application orientation, you need to stop the preview, rotate and then start it again
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
mCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
//now, recreate the camera preview
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//our app has only one screen, so we'll destroy the camera in the surface
//if you are unsing with more screens, please move this code your activity
mCamera.stopPreview();
mCamera.release();
}
}
And this is my activity, which takes a picture and save it
public class MainActivity extends Activity implements OnClickListener {
String TAG = "Main activity";
private Camera mCamera = null;
private CameraView mCameraView = null;
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// app en plein ecran
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
// CREATION DU DYNAMIQUE
final Button menu = (Button) findViewById(R.id.buttonMenu);
menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Perform action on click
Intent mainToMenu;
mainToMenu = new Intent(MainActivity.this, MenuActivity.class);
startActivity(mainToMenu);
}
});
try {
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if(mCamera != null) {
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
// quand j appuis sur un btn volume
final Button b = (Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Perform action on click
mCamera.takePicture(null, null, mPicture);
}
});
}
public static final int MEDIA_TYPE_IMAGE = 1;
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "FotoFoto");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
#Override
public void onClick(View v) {
}
}

Take picture with front camera in android service

I need to take a picture with the back camera in an android service but after reading the docs it seems you need a SurfaceView is it possible to take a picture without showing anything to the user?
Edit:
Will this work?
SurfaceTexture surfaceTexture = new SurfaceTexture(10);
Camera camera = Camera.open();
camera.getParameters().setPreviewSize(1, 1);
camera.setPreviewTexture(surfaceTexture);
camera.startPreview();
camera.takePicture(null, pictureCallback, null);
100% working . click picture from front camera using service .
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
CapturePhoto();
}
private void CapturePhoto() {
Log.d("kkkk","Preparing to take photo");
Camera camera = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
int frontCamera = 1;
//int backCamera=0;
Camera.getCameraInfo(frontCamera, cameraInfo);
try {
camera = Camera.open(frontCamera);
} catch (RuntimeException e) {
Log.d("kkkk","Camera not available: " + 1);
camera = null;
//e.printStackTrace();
}
try {
if (null == camera) {
Log.d("kkkk","Could not get camera instance");
} else {
Log.d("kkkk","Got the camera, creating the dummy surface texture");
try {
camera.setPreviewTexture(new SurfaceTexture(0));
camera.startPreview();
} catch (Exception e) {
Log.d("kkkk","Could not set the surface preview texture");
e.printStackTrace();
}
camera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFileDir=new File("/sdcard/CaptureByService");
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
pictureFileDir.mkdirs();
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "ServiceClickedPic_" + "_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator + photoFile;
File mainPicture = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(mainPicture);
fos.write(data);
fos.close();
Log.d("kkkk","image saved");
} catch (Exception error) {
Log.d("kkkk","Image could not be saved");
}
camera.release();
}
});
}
} catch (Exception e) {
camera.release();
}
}
}
You can set Width and Height of SurfaceView to 1dp and margintop to -10,so that it wont display it on screen but it functions as normal and you can Take picture without displaying Surface View to User
<SurfaceView
android:layout_width="1dp"
android:layout_height="1dp"
android:layout_marginTop="-10dp"
...
/>
in that case you can just use SurfaceTexture
SurfaceTexture surfaceTexture = new SurfaceTexture(10);
Camera camera = Camera.open();
camera.getParameters().setPreviewSize(1, 1);
camera.setPreviewTexture(surfaceTexture);
Yes it is possible. call your Camera Callback method to take picture from camera and Dont specify the size for preview and just start the preview it will work .
Omit this Step :
param.setPreviewSize(122,133);
or use
param.setPreviewSize(1, 1);

Android Front Camera Record failed

I am trying to record audio by front camera in one of my Activities using MediaRecorder. Part of the code is shown below.if I open back Camera, it works well. But if I open front Camera, there is No Runtime Error but I can't open the output MP4
part of CameraService.java
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TAG", "======= service in onStartCommand");
if (Util.checkCameraHardware(this)) {
mCamera = Util.getCameraInstance();
if (mCamera != null) {
SurfaceView sv = new SurfaceView(this);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(1, 1,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
SurfaceHolder sh = sv.getHolder();
sv.setZOrderOnTop(true);
sh.setFormat(PixelFormat.TRANSPARENT);
sh.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
Camera.Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
Camera.Parameters p = mCamera.getParameters();
List<Camera.Size> listSize;
listSize = p.getSupportedPreviewSizes();
Camera.Size mPreviewSize = listSize.get(2);
Log.v("TAG", "preview width = " + mPreviewSize.width
+ " preview height = " + mPreviewSize.height);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
listSize = p.getSupportedPictureSizes();
Camera.Size mPictureSize = listSize.get(2);
Log.v("TAG", "capture width = " + mPictureSize.width
+ " capture height = " + mPictureSize.height);
p.setPictureSize(mPictureSize.width, mPictureSize.height);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
mCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setProfile(CamcorderProfile.get(1,CamcorderProfile.QUALITY_HIGH));
mMediaRecorder.setOutputFile(Util.getOutputMediaFile(Util.MEDIA_TYPE_VIDEO).getPath());
mMediaRecorder.setPreviewDisplay(holder.getSurface());
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d("TAG", "====== IllegalStateException preparing MediaRecorder: " + e.getMessage());
} catch (IOException e) {
Log.d("TAG", "====== IOException preparing MediaRecorder: " + e.getMessage());
}
mMediaRecorder.start();
Log.d("TAG", "========= recording start");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mMediaRecorder.stop();
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder=null;
mCamera.stopPreview();
mCamera.release();
Log.d("TAG", "========== recording finished.");
}
}, 10000);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
wm.addView(sv, params);
} else {
Log.d("TAG", "==== get Camera from service failed");
}
} else {
Log.d("TAG", "==== There is no camera hardware on device.");
}
return super.onStartCommand(intent, flags, startId);
}
part of Util.java
public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(1);
} catch (Exception e) {
Log.d("TAG", "Open camera failed: " + e);
}
return c;
}
Update:
I change two lines shown below, switching to the back camera and record video well.
CameraService.java mMediaRecorder.setProfile(CamcorderProfile.get(1,CamcorderProfile.QUALITY_HIGH)); => mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
Util.java c = Camera.open(1); => c = Camera.open();
Once i get the same error in my case my i set the video sizes or wrong.
protected void startRecording() {
try {
mrec = new MediaRecorder();
mCamera.unlock();
mrec.setCamera(mCamera);
//Set audio source
mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
//set video source
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//set output format
mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
int width = 320;
int height = 240;
try {
//get the available sizes of the video
List<Size> tmpList = getSupportedVideoSizes();
final List<Size> sizeList = new Vector<Size>();
// compare the apsect ratio of the candidate sizes against the
// real ratio
Double aspectRatio = (Double.valueOf(getWindowManager()
.getDefaultDisplay().getHeight()) / getWindowManager()
.getDefaultDisplay().getWidth());
for (int i = tmpList.size() - 1; i > 0; i--) {
Double tmpRatio = Double.valueOf(tmpList.get(i).height)
/ tmpList.get(i).width;
if (EnableLog.LOG_TAG) {
Log.e("Width & height", tmpList.get(i).width + " x "
+ tmpList.get(i).height);
}
if (Math.abs(aspectRatio - tmpRatio) < .15) {
width = tmpList.get(i).width;
height = tmpList.get(i).height;
sizeList.add(tmpList.get(i));
}
}
} catch (Exception e) {
e.printStackTrace();
}
// set the size of video.
// If the size is not applicable then throw the media recorder stop
// -19 error
mrec.setVideoSize(width, height);
// Set the video encoding bit rate this changes for the high, low.
// medium quality devices
mrec.setVideoEncodingBitRate(1700000);
//Set the video frame rate
mrec.setVideoFrameRate(30);
//set audio encoder format
mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//set video encoder format
mrec.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//Show the display preview
mrec.setPreviewDisplay(surfaceHolder.getSurface());
//output file path
mrec.setOutputFile(output_path);
mrec.prepare();
mrec.start();
} catch (IllegalStateException e) {
Crashlytics.logException(e);
e.printStackTrace();
} catch (IOException e) {
Crashlytics.logException(e);
e.printStackTrace();
}
}
public List<Size> getSupportedVideoSizes() {
if (params.getSupportedVideoSizes() != null) {
return params.getSupportedVideoSizes();
} else {
// Video sizes may be null, which indicates that all the supported
// preview sizes are supported for video recording.
return params.getSupportedPreviewSizes();
}
}
This is works for me. Try that. Maybe it will help. I am not sure try this.

why does camera's live preview rotates 90 degrees?

I've written a camera application, but when I want to show the camera's live preview(before taking the picture), the preview is rotated 90 degrees! here is my camera activity's code :
public class CameraActivity extends Activity{
public static final int MEDIA_TYPE_IMAGE = 1 ;
private Camera mCamera;
private CameraPreview mPreview;
Uri photoPath ;
protected void onStop()
{
super.onStop();
mCamera.release();
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
ViewGroup.LayoutParams previewParam = preview.getLayoutParams() ;
Parameters cameraParam = mCamera.getParameters() ;
double ratio = (double)cameraParam.getPictureSize().height / (double)cameraParam.getPictureSize().width ;
// previewParam.height= cameraParam.getPictureSize().height / 5 ;
// previewParam.width = cameraParam.getPictureSize().width / 5 ;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
try
{
display.getSize(size);
}
catch(java.lang.NoSuchMethodError ignore)
{
size.x = display.getWidth();
size.y = display.getHeight() ;
}
int width = size.x;
int height = size.y;
previewParam.width = width;
previewParam.height = (int)(previewParam.width * ratio) ;
// preview.setLayoutParams(previewParam) ;
preview.addView(mPreview);
}
//Camera Classes here
private final static String TAG = "Navid";
public static Camera getCameraInstance()
{
Camera c = null ;
try
{
c = Camera.open() ;
}
catch(Exception e)
{
}
return c ;
}
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder mHolder ;
private Camera mCamera;
public CameraPreview(Context context , Camera camera)
{
super(context) ;
mCamera = camera ;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch(IOException e)
{
Log.d(TAG,"Camera Preview Failed!: "+e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder , int m , int n , int w)
{
}
public void surfaceDestroyed(SurfaceHolder holder)
{
}
}
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
}else {
return null;
}
return mediaFile;
}
//save the picture here
private PictureCallback mPicture = new PictureCallback() {
// public final static int MEDIA_TYPE_IMAGE = 1 ;
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
photoPath = Uri.fromFile(pictureFile);
if (pictureFile == null){
Log.d("Errore Doorbin", "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
// these lines are for the gallery to scan the SDCard manually
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ mediaStorageDir)));
// photoPath = Uri.fromFile(mediaStorageDir) ;
/* MediaScannerConnection.scanFile(CameraActivity.this,
new String[] { fos.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// code to execute when scanning is complete
}
});*/
// fos.close();
} catch (FileNotFoundException e) {
Log.d("Errore Doorbin", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Errore Doorbin", "Error accessing file: " + e.getMessage());
}
catch (Exception e)
{
Log.d("Errore Doorbin", "errore Kolli dade!" + e.getMessage()) ;
}
}
};
public void capture(View v)
{
//mCamera.takePicture(null, null, mPicture);
//mCamera.release();
//mCamera = getCameraInstance() ;
//mCamera.startPreview();
TakePictureTask takePicture = new TakePictureTask() ;
takePicture.execute() ;
}
public void accept(View v)
{
Intent data = new Intent() ;
data.setData(photoPath) ;
setResult(RESULT_OK, data);
finish() ;
}
public void retake(View v)
{
Button button = (Button)findViewById(R.id.button_accept);
button.setVisibility(View.GONE);
button = (Button)findViewById(R.id.button_capture) ;
button.setVisibility(View.VISIBLE) ;
button = (Button)findViewById(R.id.button_retake);
button.setVisibility(View.GONE) ;
mCamera.startPreview();
}
/**
* A pretty basic example of an AsyncTask that takes the photo and
* then sleeps for a defined period of time before finishing. Upon
* finishing, it will restart the preview - Camera.startPreview().
*/
private class TakePictureTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void result) {
// This returns the preview back to the live camera feed
Button button = (Button)findViewById(R.id.button_accept) ;
button.setVisibility(View.VISIBLE) ;
button = (Button)findViewById(R.id.button_retake) ;
button.setVisibility(View.VISIBLE);
button = (Button)findViewById(R.id.button_capture);
button.setVisibility(View.GONE);
//mCamera.startPreview();
}
#Override
protected Void doInBackground(Void... params) {
mCamera.takePicture(null, null, mPicture);
// Sleep for however long, you could store this in a variable and
// have it updated by a menu item which the user selects.
try {
Thread.sleep(3000); // 3 second preview
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
and in my application's manifest I've changed this activities orientation to portrait!
What is the problem ? why does it look like this ?
This happens to be a bug in earlier versions of Android.
A workaround is to rotate the camera by default.
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
camera.setDisplayOrientation(90);
lp.height = previewSurfaceHeight;
lp.width = (int) (previewSurfaceHeight / aspect);
} else {
camera.setDisplayOrientation(0);
lp.width = previewSurfaceWidth;
lp.height = (int) (previewSurfaceWidth / aspect);
}

Categories