The code works mostly fine. The only problem is that the onPictureTaken function never called. I need to use this function to store the image to SD Card.
MainActivity
public class MainActivity extends Activity {
//private static Camera mCamera;
//private CameraPreview mPreview;
private static String TAG = "CamraOne";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_layout);
Log.d(TAG, "setContentView end");
Intent intent = new Intent(this, CameraServiceOne.class);
Log.d(TAG,"start intent");
startService(intent);
Log.d(TAG,"run in bkgrd");
}
Camera Service
CameraService
public class CameraServiceOne extends Service{
private SurfaceHolder sHolder;
//a variable to control the camera
private static Camera mCamera;
//the camera parameters
private Parameters parameters;
private static String TAG = "CameraOne";
/** Called when the activity is first created. */
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
mCamera = Camera.open();
SurfaceView sv = new SurfaceView(getApplicationContext());
try {
mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
//set camera parameters
mCamera.setParameters(parameters);
mCamera.startPreview();
Thread.sleep(1000);
Log.d(TAG,"take pic");
mCamera.takePicture(null, null, mCall);
Log.d(TAG,"pic end");
Thread.sleep(5000);
mCamera.stopPreview();
mCamera.release();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Get a surface
sHolder = sv.getHolder();
//tells Android that this surface will have its data constantly replaced
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public static Camera.PictureCallback mCall = new Camera.PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
mCamera = null;
Log.d(TAG,"in callback");
//decode the data obtained by the camera into a Bitmap
/*
FileOutputStream outStream = null;
try{
outStream = new FileOutputStream("/sdcard/Image.jpg");
Log.d(TAG,"write pic");
outStream.write(data);
Log.d(TAG,"write end");
outStream.close();
} catch (FileNotFoundException e){
Log.d("CAMERA", e.getMessage());
} catch (IOException e){
Log.d("CAMERA", e.getMessage());
}
*/
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();
/*
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ mediaStorageDir)));
*/
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** 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.
if(Environment.getExternalStorageDirectory() == null){
Log.d("MyCameraApp","getExternalStorageDirectory null");
}
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "CameraServiceOne");
// 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 path: " +
mediaStorageDir.getPath());
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
Log.d(TAG,"write mediafile");
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cameraone"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:name=".CameraServiceOne"/>
<activity
android:name="com.example.cameraone.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Updated CameraService
public class CameraServiceOne extends Service implements SurfaceHolder.Callback{
private SurfaceHolder sHolder;
//a variable to control the camera
private static Camera mCamera;
//the camera parameters
private Parameters parameters;
private static String TAG = "CameraOne";
/** Called when the activity is first created. */
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.d(TAG,"on start");
mCamera = Camera.open();
//change sv to findViewByID
//SurfaceView sv = new SurfaceView(getApplicationContext());
LayoutInflater inflater = (LayoutInflater)
getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.camera_layout, null);
SurfaceView sv = (SurfaceView) layout.findViewById(R.id.camera_surfaceview);
parameters = mCamera.getParameters();
mCamera.setParameters(parameters);
mCamera.startPreview();
Log.d(TAG,"startPreview");
sv.post(new Runnable() { public void run() { mCamera.takePicture(null, null, mCall); } });
/*
try {
mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
//set camera parameters
mCamera.setParameters(parameters);
mCamera.startPreview();
Thread.sleep(1000);
Log.d(TAG,"take pic");
mCamera.takePicture(null, null, mCall);
Log.d(TAG,"pic end");
Thread.sleep(5000);
mCamera.stopPreview();
mCamera.release();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
//Get a surface
sHolder = sv.getHolder();
//tells Android that this surface will have its data constantly replaced
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public static Camera.PictureCallback mCall = new Camera.PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
mCamera = null;
Log.d(TAG,"in callback");
//decode the data obtained by the camera into a Bitmap
/*
FileOutputStream outStream = null;
try{
outStream = new FileOutputStream("/sdcard/Image.jpg");
Log .d(TAG,"write pic");
outStream.write(data);
Log.d(TAG,"write end");
outStream.close();
} catch (FileNotFoundException e){
Log.d("CAMERA", e.getMessage());
} catch (IOException e){
Log.d("CAMERA", e.getMessage());
}
*/
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();
/*
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ mediaStorageDir)));
*/
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** 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.
if(Environment.getExternalStorageDirectory() == null){
Log.d("MyCameraApp","getExternalStorageDirectory null");
}
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "CameraServiceOne");
// 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 path: " + mediaStorageDir.getPath());
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
Log.d(TAG,"write mediafile");
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
onPictureTaken was never called. I figured out it that because the Camera.takePicture() method was invoked many times, it caused onPictureTaken to not be called. If ShutterCallback has a code return, then onPictureTaken is also not called.
You correctly found that takePicture() should not be called before startPreview() or immediately after it. But unfortunately it's not enough to add extra sleep() between them.
The trick is that there are few callbacks that must be executed before you can issue takePicture(): a SurfaceView must be ready, and preview start playing on this SurfaceView.
So, first of all you must display the sv view. You can simply prepare a SurfaceView as part of camera_layout.xml, and instead of calling new SurfaceView(getApplicationContext()) use findViewById(R.id.camera_surface_view).
Second, add implements SurfaceHolder.Callback to your CameraServiceOne class, and implement the callbacks (see e.g. the Android tutorial).
Now, you can post (another level of async execution) takePicture() directly from the SurfaceCreated():
sv.post(new Runnable() { public void run() { mCamera.takePicture(null, null, mCall); } } });
Finally, consider using a background HandlerThread for Camera.open() and configuration: these lengthy operations may freeze the UI (main) thread for unacceptably long time.
Related
I want to use a service to take photo secretly. Here is the code:
** Takes a single photo on service start. */
public class PhotoTakingService extends Service {
static String TAG = "Khan";
private boolean isRunning = false;
#Override
public void onCreate() {
Log.d("shahjahan", "i am in photo taking service.");
super.onCreate();
Log.d(TAG, "the name of the for ground process is: " + getForgroundProcessName());
takePhoto(this);
}
#SuppressWarnings("deprecation")
private static void takePhoto(final Context context) {
final SurfaceView preview = new SurfaceView(context);
SurfaceHolder holder = preview.getHolder();
// deprecated setting, but required on Android versions prior to 3.0
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new SurfaceHolder.Callback() {
#Override
//The preview must happen at or after this point or takePicture fails
public void surfaceCreated(SurfaceHolder holder) {
showMessage("Surface created");
Camera camera = null;
try {
camera = Camera.open();
showMessage("Opened camera");
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
throw new RuntimeException(e);
}
camera.startPreview();
showMessage("Started preview");
camera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
showMessage("Took picture");
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());
}
camera.release();
}
});
} catch (Exception e) {
if (camera != null)
camera.release();
throw new RuntimeException(e);
}
}
#Override public void surfaceDestroyed(SurfaceHolder holder) {}
#Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
});
WindowManager wm = (WindowManager)context
.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
1, 1, //Must be at least 1x1
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
0,
//Don't know if this is a safe default
PixelFormat.UNKNOWN);
//Don't set the preview visibility to GONE or INVISIBLE
wm.addView(preview, params);
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** 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), "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 if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
private static void showMessage(String message) {
Log.i("Camera", message);
}
#Override public IBinder onBind(Intent intent) { return null; }
public String getForgroundProcessName()
{
ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
// Log.i("Foreground App", appProcess.processName);
// Toast.makeText(this, "the forground application is: " + appProcess.processName, Toast.LENGTH_LONG).show();
return appProcess.processName;
}
}
return "None";
}
}
But, I want to run takePhoto(this) after a regular interval in background. I tried handler, but it's not working fine:
Handler uiHandler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
int i = 0;
while(true)
{
Log.d(TAG,"I am in while.");
i++;
takePhoto(getApplicationContext());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if ( i > 5 )
break;
}
}
};
uiHandler.post(runnable);
Using above code freezes my app. Please guide me to implement above code correctly.
I am making a camera app. I followed This tutorial to capture and save images in device. By implementing this, the image is captured and saved in device's gallery. It saves the image as file. But I want to get the bitmap of captured image. Here is my implementation,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_layout);
cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
filepath = Environment.getExternalStorageDirectory();
if (checkCameraHardware(this)) {
// Create an instance of Camera
mCamera = getCameraInstance();
try {
// Get Camera Parameters
Camera.Parameters params = mCamera.getParameters();
// Set the Focus Mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.setParameters(params);
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.cameraPreview);
preview.addView(mPreview);
} catch (Exception e) {
}
}
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
#Override
protected void onPause() {
// TODO OnPause Method
super.onPause();
releaseCamera();
}
// TODO Detecting Camera Hardware
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// This device has camera
return true;
} else {
// No Camera on this Device
return false;
}
}
// TODO Accessing Camera
public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open();
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Takes the picture and write to file
File dir = new File(filepath.getAbsolutePath() + "/QR Codes/");
dir.mkdirs();
File pictureFile = getOutputMediaFile(FileColumns.MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d("PICFILE",
"Error creating media file, check storage permissions");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
updateGallery();
} catch (Exception e) {
}
}
};
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
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;
}
Convert your image from file to Bitmap. Like,
Bitmap bmp = BitmapFactory.decodeFile(urImageFilePath);
Try:
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data.length);
I Created a app that captures image and stores in the SD Card. The app seems to work fine with the previewing. But the problem is that when I run the app on my phone through eclipse the image gets captured. If I run my app in a normal way and try to capture the image, the image doesn't get captured.
I have attached my code below
My MainActivity.class
public class MainActivity extends Activity {
private ImageHandler preview;
Camera camera;
int cameraID, currentCamera;
Button capture;
FrameLayout imageLayout;
SurfaceView imgl;
private static final String TAG = "CallCamera";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* Invoking Camera and Setting the ImageHandler for preview
*/
camera = getCameraInstance();
preview = new ImageHandler(this, camera);
/*
* Getting the ID of the FrameLayout that displays the camera
*/
imageLayout = (FrameLayout) findViewById(R.id.preview_layout);
imageLayout.addView(preview);
/*
* Getting the ID of capture Button and setting its Functionality
*/
capture = (Button) findViewById(R.id.cameraButton);
capture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(null, null, null, pic);
}
});
}
private Camera getCameraInstance() {
// TODO Auto-generated method stub
Camera cam = null;
try {
cam = Camera.open();
} catch (Exception e) {
}
return cam;
}
PictureCallback pic = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
// File picFile = getOutputPhotoFile();
// if(picFile == null){
// return;
// }
//
// try{
// FileOutputStream fos = new FileOutputStream(picFile);
// fos.write(data);
// fos.close();
//
// }catch(FileNotFoundException e){
//
// }catch (IOException e){
//
// }
//
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
Log.d(TAG, "Can't create directory to save image.");
Toast.makeText(getApplicationContext(),
"Can't create directory to save image.",
Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator
+ photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(getApplicationContext(),
"New Image saved:" + photoFile, Toast.LENGTH_LONG)
.show();
} catch (Exception error) {
Log.d(TAG,
"File" + filename + "not saved: " + error.getMessage());
Toast.makeText(getApplicationContext(),
"Image could not be saved.", Toast.LENGTH_LONG).show();
}
camera.startPreview();
}
private File getDir() {
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(sdDir, "CameraAPIDemo");
}
};
// private File getOutputPhotoFile() {
//
// File directory = new File(
// Environment
// .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
// "IMAGES_CAMERA");
//
// if (!directory.exists()) {
// if (!directory.mkdirs()) {
// Log.e(TAG, "Failed to create storage directory.");
// return null;
// }
// }
//
// String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss")
// .format(new Date());
//
// return new File(directory.getPath() + File.separator + "IMG_"
// + timeStamp + ".jpg");
// }
//
#Override
public void onResume() {
super.onResume();
if (camera == null) {
camera = Camera.open();
preview.setCamera(camera);
}
}
}
My Preview/ ImageHandler.class
public class ImageHandler extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
private Camera imgCamera;
List<Size> imgSupportedPreviewSizes;
public ImageHandler(Context context, Camera camera) {
super(context);
// TODO Auto-generated constructor stub
this.imgCamera = camera;
this.holder = this.getHolder();
this.holder.addCallback(this);
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
try {
imgCamera.setPreviewDisplay(holder);
imgCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
imgCamera.setPreviewDisplay(holder);
imgCamera.startPreview();
imgCamera.setDisplayOrientation(90);
} catch (Exception e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
imgCamera.stopPreview();
imgCamera.release();
}
public void setCamera(Camera camera) {
imgCamera = camera;
if (imgCamera != null) {
imgSupportedPreviewSizes = imgCamera.getParameters()
.getSupportedPreviewSizes();
requestLayout();
}
}
}
I want to be able to capture image when I run the app normally through my phone.
I am working on a custom Camera activity for my application.
I was following the instruction from the Android Developers site here:
http://developer.android.com/guide/topics/media/camera.html
Everything seems to works fine, except the Callback function is not called and the picture is not saved. Here is my code:
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private static final String TAG = "CameraActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.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);
preview.addView(mPreview);
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "will now take picture");
mCamera.takePicture(null, null, mPicture);
Log.v(TAG, "will now release camera");
mCamera.release();
Log.v(TAG, "will now call finish()");
finish();
}
});
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.v(TAG, "Getting output media file");
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.v(TAG, "Error creating output file");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.v(TAG, e.getMessage());
} catch (IOException e) {
Log.v(TAG, e.getMessage());
}
}
};
private static File getOutputMediaFile() {
String state = Environment.getExternalStorageState();
if (!state.equals(Environment.MEDIA_MOUNTED)) {
return null;
}
else {
File folder_gui = new File(Environment.getExternalStorageDirectory() + File.separator + "GUI");
if (!folder_gui.exists()) {
Log.v(TAG, "Creating folder: " + folder_gui.getAbsolutePath());
folder_gui.mkdirs();
}
File outFile = new File(folder_gui, "temp.jpg");
Log.v(TAG, "Returnng file: " + outFile.getAbsolutePath());
return outFile;
}
}
After clicking the Button, I get logs: "will now take picture", "will now release camera" and "will now call finish". The activity finishes succesfully, but the Callback function was not called during the
mCamera.takePicture(null, null, mPicture);
function (There were no logs from the mPicture callback or getMediaOutputFile functions) and there is no file in the location that was specified.
Any ideas? :)
Much thanks!
The call to mCamera.takePicture() is asynchronous. That means that the call completes immediately, but the actual picture taking and processing happens sometime later. However, you do this immediately upon return from the call to mCamera.takePicture():
Log.v(TAG, "will now release camera");
mCamera.release();
Log.v(TAG, "will now call finish()");
finish();
That means that you have released the camera resources and finished the Activity before the camera gets a chance to actually take the picture and call you back.
You need to move that code into the callback method onPictureTaken() so that you release the resources and finish the Activity after the callback occurs.
Do it like this for taking multiple images on single Click Using SurfaceView Custom Camera
clickbtn.setOnClickListener(new OnClickListener() {
#SuppressWarnings("deprecation")
#Override
public void onClick(View v) {
for (int i = 0; i < 5; i++) {
mcamera = mPreview.getCamera();
getimage(mcamera);
Toast.makeText(getApplicationContext(),
"multiple image count=" + i, 1000).show();
}
if (mPreview == null) {
mPreview = new CamLayer(MainActivity.this);
}
}
});
and
public static void getimage(Camera mcamera) {
PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile();
Log.e("path file 11111111", ""+pictureFile);
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (Exception e) {
}
}
};
try {
mcamera.startPreview();
mcamera.takePicture(null, null, mPicture);
Thread.sleep(2000);
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"Sunil3");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
File mediaFile = new File(String.format(mediaStorageDir+File.separator+"%d.jpg", System.currentTimeMillis()));
return mediaFile;
}
I'm working on an app where you access and create a folder immediately after clicking get access to the camera and after a bit of photo shots, saving it in this latest in pdf. But I do not know how to turn a jpg to pdf.
I read something about iText but I do not know how to implement it
public class CameraView extends Activity implements SurfaceHolder.Callback{
protected static final String TAG = null;
/* VARIABILI PRIVATE */
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private boolean mPreviewRunning;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSPARENT); //aggiungo il traslucido
requestWindowFeature(Window.FEATURE_NO_TITLE); //no barra titolo
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //full screen
setContentView(R.layout.main);
ImageButton buttonPicture = (ImageButton) findViewById(R.id.camera_surface_button);
buttonPicture.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
mCamera.takePicture(null, null, jpegCallback);
}
});
mSurfaceView = (SurfaceView)findViewById(R.id.camera_surface);
mSurfaceHolder = mSurfaceView.getHolder(); //recupero l'holder della surfaceview
mSurfaceHolder.addCallback(this); //faccio la bind alla nostra activity
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //tipo di surface, suggerito nei tutorial ufficiali
}
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
//riparte la preview della camera
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Throwable e = null;
Log.d(TAG, "Error creating media file, check storage permissions: " +
e.getMessage());
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());
}
mCamera.startPreview();
}
};
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
if (mPreviewRunning)
mCamera.stopPreview();
//setto le preferenze
Camera.Parameters p = mCamera.getParameters(); //prendo le preferenze della camera
p.setPreviewSize(arg2, arg3);
ArrayList<Size> list = (ArrayList<Size>) p.getSupportedPictureSizes(); //recuepro le risoluzioni supportate dalla camera
int picture_width = list.get(list.size()-1).width;
int picture_height = list.get(list.size()-1).height;
p.setPictureSize(picture_width, picture_height); //setto la camera alla risoluzione pi bassa
p.setJpegQuality(80); // qualitˆ compressione JPEG
// salvo le pref
mCamera.setParameters(p);
try {
//lancio la preview
mCamera.setPreviewDisplay(arg0);
mCamera.startPreview();
mPreviewRunning = true;
} catch (IOException e) {
//gestione errore
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
}
public static final int MEDIA_TYPE_IMAGE = 1;
final Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
final File getOutputMediaFile(int type){
String direct = this.getIntent().getStringExtra("key");
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES ),direct );
// 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;
}
}
Give me a hand thanks
If you have a web server doing the conversion,
mpdf tcpdf fpdf