In my app I am capturing images automatically using a service.
From my service I am opening the camera activity.
Camera Activity
public class CameraActivity extends Activity {
private static final String TAG = "CameraDemo";
SharedPreferences pref;
CameraPreview preview;
Button click;
// enter email adress from where the email will be sent
String fromPassWord;
int cameraType;
private static final int FRONT_CAMERA = 0;
private static final int BACK_CAMERA = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
cameraType = getIntent().getIntExtra("cameraType",BACK_CAMERA);
preview = new CameraPreview(this,cameraType);
((FrameLayout) findViewById(com.abc.xyz.R.id.preview)).addView(preview);
handler.sendEmptyMessageDelayed(0, 100);
Log.d(TAG, "onCreate'd");
}
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
try{
if(preview.camera != null ){
preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
}else{
finish();
}
}catch (Exception e) {
// TODO: handle exception
finish();
}
};
};
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
Log.v(TAG, "onShutter'd");
}
};
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
Log.v(TAG, "onPictureTaken - raw");
}
};
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
try {
//my method for storing image
StoreByteImage(data, 75, "ImageName");
Log.v("on picture taken", "picture callback");
} catch (Exception e) {
Log.d(TAG, "Exception--------------------1");
e.printStackTrace();
}
finish();
}
};
}
CameraPreview.java
class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
private static final String TAG = "Preview";
SurfaceHolder mHolder;
public Camera camera;
int cameraType;
Context _context;
private static final int FRONT_CAMERA = 0;
private static final int BACK_CAMERA = 1;
//SurfaceHolder controls the surface size and format, edit the pixels in the surface, and monitor changes to the surface
CameraPreview(Context context, int type){
super(context);
//Return the SurfaceHolder providing access and control over this SurfaceView's underlying surface
mHolder = getHolder();
//Add a callback interface to this holder
mHolder.addCallback(this);
//Set the surface type
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.cameraType = type;
_context = context;
}
//Create a surface
public void surfaceCreated(SurfaceHolder sHolder){
if(cameraType == FRONT_CAMERA){
try{
camera = openFrontFacingCameraGingerbread(); //method to open camera...
Log.v("cameraFornt", "value"+camera);
}catch (Exception e) {
e.printStackTrace();
}
}
}else{
//do nothing
}
if(camera == null)
return;
try{
camera.setPreviewDisplay(sHolder);
//Installs a callback to be invoked for every preview frame in addition to displaying them on the screen
camera.setOneShotPreviewCallback(new PreviewCallback(){
//Called as preview frames are displayed
public void onPreviewFrame(byte[] data, Camera arg1){
CameraPreview.this.invalidate();
}
});
} catch (Exception e){
e.printStackTrace();
}
}
//called immediately before a surface is being destroyed
public void surfaceDestroyed(SurfaceHolder sHolder){
if(camera == null){
return;
}
Log.v("Surface dESTroyed ","Camera Preview");
camera.release();
}
Log.v("Camera",""+camera);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h){
Log.v("SurfaceChangesCalled", "true");
if(camera == null){
return;
}
}
public void draw(Canvas canvas){
super.draw(canvas);
//The Paint class holds the style and color information about how to draw geometries, text and bitmaps
Paint paint = new Paint(Color.RED);
Log.d(TAG, "draw");
Log.v("Draw", "Canvas");
//Draw the text, with origin at (canvas.getWidth()/2, canvas.getHeight()/2), using the specified paint
canvas.drawText("Preview", canvas.getWidth() / 2, canvas.getHeight() / 2, paint);
}
}
Now my problem is that i got ANR when my main application is open and the camera activity starts. it freezes at the line camera.release();
But when my main app is not open it works like a charm.
I also tried releasing camera in onPause() method of CameraActivity but no luck.
Related
Is that possible to add camera preview inside my gameview ?
I tried to add the camera preview inside the gameview this errors appear.
E/SurfaceHolder: Exception locking surface java.lang.IllegalArgumentException
It seem like something wrong with my gameloop
but i have no idea how to solve it.
Anyone know how to solve the problem?
My GameLoop
public class MainThread extends Thread {
public static final int MAX_FPS = 30;
private double averageFPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean running){
this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel){
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
#Override
public void run() {
long startTime;
long timeMillis = 1000/MAX_FPS;
long waitTime;
int frameCount = 0;
long totalTime = 0;
long targetTime = 1000/MAX_FPS;
while(running){
startTime = System.nanoTime();
canvas = null;
try{
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
this.gamePanel.update();
this.gamePanel.draw(canvas);
}
} catch (Exception e) {e.printStackTrace();}
finally {
if (canvas != null){
try{
surfaceHolder.unlockCanvasAndPost(canvas);
}catch (Exception e) {e.printStackTrace();}
}
}
timeMillis = (System.nanoTime() - startTime) / 1000000;
waitTime = targetTime - timeMillis;
try{
if(waitTime > 0 )
this.sleep(waitTime);
}catch (Exception e) {e.printStackTrace();}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == MAX_FPS){
averageFPS = 1000/((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
System.out.println(averageFPS);
}
}
}
}
My GameView
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
private ObstacleManager obstacleManager;
private SurfaceHolder mHolder;
private Camera mCamera;
public GamePanel(Context context, Camera camera) {
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
thread = new MainThread(mHolder, this);
obstacleManager = new ObstacleManager(100, 100, Color.BLACK);
setFocusable(true);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try{
//when the surface is created, we can set the camera to draw images in this surfaceholder
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
thread = new MainThread(holder, this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//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 holder) {
boolean retry = false;
while(retry){
try{
thread.setRunning(false);
thread.join();
}catch (Exception e) {e.printStackTrace(); }
retry = false;
}
mCamera.stopPreview();
mCamera.release();
}
public void update(){
obstacleManager.update();
}
#Override
public void draw(Canvas canvas){
super.draw(canvas);
//canvas.drawColor(Color.WHITE);
obstacleManager.draw(canvas);
}
}
My MainActivity
public class Main2Activity extends Activity {
//declaring gameview
private GameView gameView;
private Camera mCamera;
private FrameLayout frameLayout;
private GamePanel gamePanel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
Constants.SCREEN_WIDTH = dm.widthPixels;
Constants.SCREEN_HEIGHT = dm.heightPixels;
try {
mCamera = Camera.open(0);//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if (mCamera != null) {
frameLayout = (FrameLayout) findViewById(R.id.gameView);
gamePanel = new GamePanel(this, mCamera);
frameLayout.addView(gamePanel);
}
}
}
You cannot use the same surface for both camera preview and canvas draw. You can create two surfaces, one next to the other, but don't even try to put one on top of the other, they will not keep the z-order reliably. The best approach is to switch the camera preview to SurfaceTexture, and use the same OpenGL context for drawing your game and camera preview.
I want to continuously receive frames from the camera and manipulate them. Since the manipulation will be a CPU heavy task, i have opened the camera on a separate handler thread so that any callbacks land on that thread as well.
However, the problem that i am having is that my onPreviewFrame() never gets called, and i cannot seem to figure out why. I tried but i cannot figure out. There is no error either.
I understand, in order for the PreviewCallbacks to occur, i need to do the following:
Open Camera
Set Preview Display (a camera preview)
Start the preview
I have done all of these and the preview even shows perfectly in the app UI. I wonder what part i am missing or doing wrong. Following is my relevant code.
ODFragment.java
public class ODFragment extends Fragment {
static View rootView;
static Context mainActivityContext;
static final String TAG = "DBG_" + "ODFragment";
static Camera mCamera;
static CameraPreview mCameraPreview;
static FrameLayout frameLayout_cameraLens;
static CameraHandlerThread mCameraHandlerThread = null;
static Handler mUiHandler = new Handler();
//static TessBaseAPI tessBaseAPI = new TessBaseAPI();
public ODFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_od, container, false);
mainActivityContext = this.getActivity();
//one time tasks
frameLayout_cameraLens = (FrameLayout) rootView.findViewById(R.id.frameLayout_cameraLens);
setCameraViewDimensions();
return rootView;
}
#Override
public void onResume() {
super.onResume();
//1 open camera
if (mCameraHandlerThread == null) {
mCameraHandlerThread = new CameraHandlerThread("Camera Handler Thread");
}
if (!mCameraHandlerThread.isAlive() || mCameraHandlerThread.getCamera()==null)
{
synchronized (mCameraHandlerThread) {
Log.d(TAG, "onResume: starting mCameraHandlerThread");
mCameraHandlerThread.start();
mCameraHandlerThread.openCamera();
}
}
//rest of the steps will be invoked (hookOpenedCamera()) by cameraHandlerThread
}
public static void hookOpenedCamera(){
mUiHandler.post(new Runnable() {
#Override
public void run() {
//2 create camera and camera preview
mCamera = mCameraHandlerThread.getCamera();
mCameraPreview = new CameraPreview(getMainActivityContext(), mCamera);
//3 add cameraPreview to layout
frameLayout_cameraLens.addView(mCameraPreview);
//4 start preview
mCamera.startPreview();
//5 hook previewCallback
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) { //TODO: incomplete
Log.d(TAG, "onPreviewFrame: called");
}
});
}
});
}
#Override
public void onPause() {
super.onPause();
//-4
mCamera.stopPreview();
//-3
frameLayout_cameraLens.removeView(mCameraPreview);
//-2
mCameraPreview = null;
mCamera = null;
//-1
mCameraHandlerThread.setCamera(null);
mCameraHandlerThread.quit();
mCameraHandlerThread = null;
}
private void setCameraViewDimensions() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
//calculate dimensions of cameraLens and height of ROI
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
final int width = displaymetrics.widthPixels;
final int height = (int) (width * 1.33333333334);
final int ROIHeight = height / 5;
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d(TAG, "run: frameLayout_cameraLens dim (BEFORE): "+frameLayout_cameraLens.getLayoutParams().width+" x "+frameLayout_cameraLens.getLayoutParams().height);
//set dimensions of cameraLens
frameLayout_cameraLens.getLayoutParams().width = width;
frameLayout_cameraLens.getLayoutParams().height = height;
frameLayout_cameraLens.requestLayout();
//set height of ROI
LinearLayout linearLayout = (LinearLayout) rootView.findViewById(R.id.ROI);
linearLayout.getLayoutParams().height = ROIHeight;
linearLayout.requestLayout();
Log.d(TAG, "run: frameLayout_cameraLens dim (AFTER): " +frameLayout_cameraLens.getLayoutParams().width+" x "+frameLayout_cameraLens.getLayoutParams().height);
}
});
}
});
thread.run();
}
public static Context getMainActivityContext() {
return mainActivityContext;
}
}
CameraHandlerThread.java
public class CameraHandlerThread extends HandlerThread {
static final String TAG = "DBG_" + "CameraHandlerThread";
Handler mCameraHandler = null;
Camera mCamera = null;
public CameraHandlerThread(String name) {
super(name);
}
#Override
public synchronized void start() {
super.start();
//prepare handler
if (mCameraHandler == null) {
mCameraHandler = new Handler(getLooper());
}
}
void openCamera() {
mCameraHandler.post(new Runnable() {
#Override
public void run() {
try {
//done on cameraHandlerThread (step 1)
mCamera = Camera.open();
//done on UiThread (steps 2, 3, 4)
ODFragment.hookOpenedCamera();
}
catch (RuntimeException e) {
Log.e(TAG, "failed to open camera");
}
}
});
}
public Camera getCamera() {
return this.mCamera;
}
public void setCamera(Camera camera) {
this.mCamera = camera;
}
}
CameraPreview.java
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
static final String TAG = "DBG_" + "CameraPreview";
private Camera.Size mPreviewSize = null;
public CameraPreview(Context context){
super(context);
}
public CameraPreview(Context context, Camera mCamera) {
super(context);
//Log.d(TAG, "CameraPreview() initialized");
//mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
setCamera(mCamera);
mHolder = getHolder();
mHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview
try {
mCamera.setDisplayOrientation(90); //because only supporting portrait currently
mCamera.setPreviewDisplay(holder);
//mCamera.startPreview();
//Log.d(TAG, "surfaceCreated(): Started camera preview");
} catch (IOException e) {
Log.d(TAG, "surfaceCreated(): Error setting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// 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
}
// set preview size and make any resize, rotate or
// reformatting changes here
Camera.Parameters cameraParameters = mCamera.getParameters();
//change camera preview size
cameraParameters.setPreviewSize(getPreviewSize().width, getPreviewSize().height);
//continuous autofocus
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
//set focus area to top part of the camera view //TODO
//cameraParameters.setFocusAreas();
//set parameters now
mCamera.setParameters(cameraParameters);
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
//Log.d(TAG, "surfaceChanged(): Restarted camera preview");
} catch (Exception e){
Log.d(TAG, "surfaceChanged(): Error starting camera preview: " + e.getMessage());
}
}
private Camera.Size getPreviewSize() {
if (mPreviewSize == null) {
List<Camera.Size> mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
mPreviewSize = mSupportedPreviewSizes.get(mSupportedPreviewSizes.size() - 6);
Log.d(TAG, "getPreviewSize(): Camera Preview Size selected: " + mPreviewSize.width + " x " + mPreviewSize.height);
}
return mPreviewSize;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
//Log.d(TAG, "surfaceDestroyed() invoked");
}
public void setCamera(Camera camera) {
this.mCamera = camera;
}
}
Thank you in advance
SOLVED
I realized that my PreviewCallback does get hooked. But after that, the surfaceChanged() gets called at a point, which stops and then starts the CameraPreview. This removes my callback.
So, i have to invoke my callback hooking routine, everywhere that i am invoking startPreview
I'm a newbie in Android and I've been trying to make an Android camera application that is supposed to be able to capture 5 images when we click the camera button. But the code I'm working on doesn't seem to work. Is there anyone that can help please? So far, this is the code:
public class CameraDemo extends Activity {
private static final String TAG = "CameraDemo";
Camera camera;
Preview preview;
Button buttonClick;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview = new Preview(this);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
buttonClick = (Button) findViewById(R.id.buttonClick);
buttonClick.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
int count = 0;
while(count < 5){
preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
count++;
try {
wait(1000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
});
Log.d(TAG, "onCreate'd");
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
// write to local sandbox file system
// outStream = CameraDemo.this.openFileOutput(String.format("%d.jpg", System.currentTimeMillis()), 0);
// Or write to sdcard
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
}
And this is the other class named Preview:
class Preview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "Preview";
SurfaceHolder mHolder;
public Camera camera;
Preview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Preview.this.invalidate();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
camera.stopPreview();
camera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
Paint p= new Paint(Color.RED);
Log.d(TAG,"draw");
canvas.drawText("PREVIEW", canvas.getWidth()/2, canvas.getHeight()/2, p );
}
}
I am developing this app which requires access to the camera. I have accessed it well. But there are two issues.
The preview is all stretched when the phone is vertical. Secondly, the camera preview isn't visible when I resume the app. The camera.open() function does opens the camera but I am not able to see the preview. I have tried all the help available on the forum but nothing is actually solving my problem.
-Thanks in advance!
//Camera Activity file
#SuppressLint("SimpleDateFormat")
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private FrameLayout preview;
private Button bCapture;
private Button bGallery;
private static final String TAG = "CameraActivity";
private static final int PICK_IMAGE_REQUEST = 1;
private TextView tvCheck;
public final static String EXTRA_MESSAGE = "com.epfl.mycamera.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_camera);
if (checkCameraHardware(getBaseContext())){
// 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, CameraActivity.this);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
//Adding Camera Button
bCapture = (Button) findViewById(R.id.bCapture);
//Button Listener for storing images
bCapture.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, null, jpegCallback);
mCamera.startPreview();
Log.d(TAG, "takePicture");
}
});
//Adding Gallery Button
bGallery = (Button) findViewById (R.id.bGallery);
bGallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tvCheck = (TextView) findViewById (R.id.tvCheck);
selectImageFromGallery();
}
});
}
Log.d(TAG, "OnCreate");
}
/******************************************************************/
public void selectImageFromGallery() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"),PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int aRequestCode, int aResultCode, Intent aData) {
switch (aRequestCode) {
case PICK_IMAGE_REQUEST:
handleImage(aData);
break;
default:
tvCheck.setText("You can only select images.");
break;
}
super.onActivityResult(aRequestCode, aResultCode, aData);
}
private void handleImage(Intent aData) {
if ((aData != null) && (aData.getData() != null)) {
Uri selectedImage = aData.getData();
String[] filePathColumn = {MediaColumns.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
Log.d("ImageActivity", "After extracting file Path");
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Log.d("ImageActivity", "After closing the cursor");
setContentView(R.layout.activity_image_old); //setting the view to the image
ImageView imgView = (ImageView) findViewById(R.id.ivGallery);
imgView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
Button bLiveCamera = (Button) findViewById(R.id.bCameraPreview);
bLiveCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setContentView(R.layout.activity_camera);
mCamera.startPreview();
}
});
}
else {
tvCheck.setText("You did not select an image");
}
}
/****************************************************************/
/** Stores jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
try {
File mediaStorageDir = new File(Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCamera");
// Saving image to the SD CARD with a file operation
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +"IMG_"+ timeStamp + ".jpg");
FileOutputStream outStream = new FileOutputStream(mediaFile);
outStream.write(data);
outStream.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
} Log.d(TAG, "onPictureTaken - jpeg");
}
};
/***************************************************************/
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
Log.d(TAG, "Camera Available");
return true;
} else {
Log.d(TAG, "No Camera Found");
return false;
}
}
/** A safe way to get an instance of the Camera object. */
public Camera getCameraInstance(){
Camera c = null;
try {
int i = Camera.getNumberOfCameras();
releaseCamera(); //in case camera is being accessed by any other app.
Log.d(TAG, "Number of Cameras "+i +"\n");
c = Camera.open(); // attempt to get a Camera instance
Log.d(TAG, "Camera Opened");
}
catch (Exception e){
Log.d(TAG, "Camera Can't Be Accessed");
}
return c; // returns null if camera is unavailable
}
#Override
protected void onPause() {
super.onPause();
releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera(){
if (mCamera != null){
mPreview.getHolder().removeCallback(mPreview);
mCamera.release(); // release the camera for other applications
}
}
#Override
public void onResume() {
super.onResume();
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
getCameraInstance();
mCamera.startPreview();
}
}
}
this is my camera preview class:
#SuppressLint({ "ViewConstructor", "SdCardPath" })
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private SurfaceHolder mHolder;
private Camera mCamera;
private Size mPreviewSize;
// private Activity CameraActivity;
#SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera, Activity activity) {
super(context);
mCamera = camera;
//CameraActivity = activity;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
//add camera preview call back here.
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// 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
}
// set preview size and make any resize, rotate or
// reformatting changes here
Camera.Parameters parameters = mCamera.getParameters();
List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
mPreviewSize = localSizes.get(0);
Log.d(TAG, "Width " + mPreviewSize.width);
Log.d(TAG, "Height " + mPreviewSize.height);
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height );
mHolder.setFixedSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
//start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.setDisplayOrientation(90);
//setCameraDisplayOrientation(CameraActivity, 0, mCamera);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
You create a CameraPreview only onCreate() of your Activity. But the camera instance is released onPause(), and a new one is opened onResume(). Therefore, you need to set the surface again.
I am developing a custom camera application and testing on two galaxy tablets.. one 7inch and one 10inch.. the 10 inch works great but on the 7inch, when i take a picture, it freezes the camera preview and the logCat stops at CAMERA SNAP, CLICKED log in my btn_snap_pic on click in my customcamera class with no error. the app doesn't crash just hangs.. and if i back out of it and open the app again i get a "fail to connect to camera" i assume that this error is because when my app froze and i backed out, the camera never got released.. anyway, below is my both my CustomCamera class and my CamLayer which is my preview..
public class CustomCamera extends Activity{
String camFace ="back";
FrameLayout frame;
RelativeLayout rel;
CamLayer camPreview;
ImageView btn_snap_pic;
ImageView btn_switch_cam;
String TAG = "custom cam";
public void onCreate(Bundle savedInstanceState)
{
Bitmap btnSwitch = BitmapFactory.decodeResource(this.getResources(),
R.drawable.btn_switch_camera);
Bitmap btnSnap = BitmapFactory.decodeResource(this.getResources(),
R.drawable.btn_take_picture);
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//Set Screen Orientation
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
RelativeLayout.LayoutParams buttonS = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams buttonT = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams cam = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
cam.addRule(RelativeLayout.BELOW);
buttonS.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
buttonT.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
buttonT.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
try{
//Create Intance of Camera
camPreview = new CamLayer(this.getApplicationContext(),camFace);
//Relative view for everything
rel = new RelativeLayout(this);
// set as main view
setContentView(rel);
//FrameLayOut for camera
frame = new FrameLayout(this);
// add Camera to view
frame.setLayoutParams(cam);
frame.addView(camPreview);
rel.addView(frame);
btn_switch_cam = new ImageView (this);
btn_switch_cam.setImageBitmap(btnSwitch);
btn_switch_cam.setLayoutParams(buttonS);
buttonS.rightMargin = 25;
buttonS.topMargin = 25;
rel.addView(btn_switch_cam);
btn_switch_cam.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Log.v("CAMERA Switch", "CLICKED");
//frame.removeView(camPreview);
if(camFace.equals("front")){
camFace = "back";
}else{
camFace = "front";
}
//camPreview.stopCamera();
frame.removeView(camPreview);
restartCam();
//camPreview.switchCam(camFace);
}
});
btn_snap_pic = new ImageView(this);
btn_snap_pic.setImageBitmap(btnSnap);
btn_snap_pic.setLayoutParams(buttonT);
buttonT.rightMargin = 25;
buttonT.bottomMargin = 25;
rel.addView(btn_snap_pic);
btn_snap_pic.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Log.v("CAMERA Snap", "CLICKED");
camPreview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
}
});
} catch(Exception e){}
}
public void restartCam(){
camPreview = new CamLayer(this.getApplicationContext(),camFace);
frame.addView(camPreview);
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format(
"/sdcard/LC/images/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
}
AND THE CAMLAYER:
public class CamLayer extends SurfaceView implements SurfaceHolder.Callback {
Camera camera;
SurfaceHolder previewHolder;
String camID;
private static final String TAG = "Cam Preview";
public CamLayer(Context context, String facing)
{
super(context);
camID = facing;
previewHolder = this.getHolder();
previewHolder.addCallback(this);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
startCamera();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Parameters params = camera.getParameters();
//params.setPreviewSize(width, height);
//params.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(params);
camera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder arg0)
{
//camera.stopPreview();
//camera.release();
stopCamera();
}
public void onResume() {
//camera.startPreview();
startCamera();
}
public void onPause() {
// TODO Auto-generated method stub
//camera.stopPreview();
stopCamera();
}
public void switchCam(String newCamId) {
/*camera.stopPreview();
//camera.release();
if(camID.equals("front")){
camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
}else{
camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}*/
//camera.startPreview();
//camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
stopCamera();
camID = newCamId;
startCamera();
}
public void stopCamera(){
System.out.println("stopCamera method");
if (camera != null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
previewHolder.removeCallback(this);
previewHolder = null;
}
}
private void startCamera(){
if(camID.equals("front")){
camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
}else{
camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}
try {
camera.setPreviewDisplay(previewHolder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
//FileOutputStream outStream = null;
/*try {
//outStream = new FileOutputStream(String.format(
//"/sdcard/%d.jpg", System.currentTimeMillis()));
//outStream.write(data);
//outStream.close();
Log.d(TAG, "onPreviewFrame - wrote bytes: "
+ data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}*/
//CamLayer.this.invalidate();
}
});
}
catch (Throwable e){ Log.w("TAG,", "failed create surface !?!?"); }
}
public void draw(Canvas canvas) {
super.draw(canvas);
Paint p = new Paint(Color.RED);
Log.d(TAG, "draw");
canvas.drawText("PREVIEW", canvas.getWidth() / 2,
canvas.getHeight() / 2, p);
}
}
This thread says raw is not supported
https://groups.google.com/forum/?fromgroups#!topic/android-developers/D43AdrbP9oE
A raw image would consume too much memory is my guess. Other than that, I'm also disappointed its not supported.