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.
Related
I am implementing android-gpuimage library in my code.
https://github.com/CyberAgent/android-gpuimage
I used the camera code of the sample project. Everyting works fine, but whenever I switch the camera, front camera opens in the side in a small view. I want the front camera to occupy the whole Surfaceview.
Here is my code:
public class CameraActivity extends Activity implements OnSeekBarChangeListener, OnClickListener {
private GPUImage mGPUImage;
private CameraHelper mCameraHelper;
private CameraLoader mCamera;
private GPUImageFilter mFilter;
private int cameraId;
private FilterAdjuster mFilterAdjuster;
static int camerastate=0;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
((SeekBar) findViewById(R.id.seekBar)).setOnSeekBarChangeListener(this);
findViewById(R.id.filter).setOnClickListener(this);
findViewById(R.id.flipCamera).setOnClickListener(this);
findViewById(R.id.captureImage).setOnClickListener(this);
cameraId = CameraInfo.CAMERA_FACING_BACK;
mGPUImage = new GPUImage(this);
mGPUImage.setImage(mImage);
mGPUImage.setFilter(mGPUImageFilter);
mGPUImage.getBitmapWithFilterApplied();*/
mGPUImage.setGLSurfaceView((GLSurfaceView) findViewById(R.id.surfaceView));
mCameraHelper = new CameraHelper(this);
mCamera = new CameraLoader();
}
#Override
protected void onResume() {
super.onResume();
mCamera.onResume();
}
#Override
protected void onPause() {
mCamera.onPause();
super.onPause();
}
#Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.filter:
GPUImageFilterTools.showDialog(this, new OnGpuImageFilterChosenListener() {
#Override
public void onGpuImageFilterChosenListener(final GPUImageFilter filter) {
switchFilterTo(filter);
}
});
break;
case R.id.captureImage:
if (mCamera.mCameraInstance.getParameters().getFocusMode().equals(
Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
takePicture();
} else {
mCamera.mCameraInstance.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(final boolean success, final Camera camera) {
takePicture();
}
});
}
break;
case R.id.flipCamera:
mCamera.switchCamera();
break;
}
}
private void takePicture() {
// TODO get a size that is about the size of the screen
Camera.Parameters params = mCamera.mCameraInstance.getParameters();
params.setRotation(90);
mCamera.mCameraInstance.setParameters(params);
for (Camera.Size size : params.getSupportedPictureSizes()) {
Log.i("ASDF", "Supported: " + size.width + "x" + size.height);
}
mCamera.mCameraInstance.takePicture(null, null,
new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, final Camera camera) {
final File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d("ASDF",
"Error creating media file, check storage permissions");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("ASDF", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("ASDF", "Error accessing file: " + e.getMessage());
}
data = null;
Bitmap bitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath());
mGPUImage1.setImage(pictureFile);
mGPUImage1.setFilter(new GPUImageSepiaFilter());
final GLSurfaceView view = (GLSurfaceView) findViewById(R.id.surfaceView);
view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mGPUImage1.saveToPictures(bitmap1, "GPUImage",
System.currentTimeMillis() + ".jpg",
new OnPictureSavedListener() {
#Override
public void onPictureSaved(final Uri
uri) {
pictureFile.delete();
camera.startPreview();
view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
});
Log.e("Activity", "GPUIMAGE " + mGPUImage.toString());
}
});
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private static File getOutputMediaFile(final 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 void switchFilterTo(final GPUImageFilter filter) {
if (mFilter == null
|| (filter != null && !mFilter.getClass().equals(filter.getClass()))) {
mFilter = filter;
mGPUImage.setFilter(mFilter);
mFilterAdjuster = new FilterAdjuster(mFilter);
}
}
#Override
public void onProgressChanged(final SeekBar seekBar, final int progress,
final boolean fromUser) {
if (mFilterAdjuster != null) {
mFilterAdjuster.adjust(progress);
}
}
#Override
public void onStartTrackingTouch(final SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(final SeekBar seekBar) {
}
private class CameraLoader {
int mCurrentCameraId = 0;
Camera mCameraInstance;
public void onResume() {
setUpCamera(mCurrentCameraId);
}
public void onPause() {
releaseCamera();
}
public void switchCamera() {
releaseCamera();
mCurrentCameraId = (mCurrentCameraId + 1) % mCameraHelper.getNumberOfCameras();
setUpCamera(mCurrentCameraId);
}
private void setUpCamera(int id) {
Log.e("Activity", "ID1 " + id);
mCameraInstance = getCameraInstance(id);
Camera.Parameters parameters = mCameraInstance.getParameters();
// TODO adjust by getting supportedPreviewSizes and then choosing
// the best one for screen size (best fill screen)
if (parameters.getSupportedFocusModes().contains(
Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
parameters.setPictureSize(640,480);
mCameraInstance.setParameters(parameters);
int orientation = mCameraHelper.getCameraDisplayOrientation(
CameraActivity.this, mCurrentCameraId);
CameraInfo2 cameraInfo = new CameraInfo2();
mCameraHelper.getCameraInfo(mCurrentCameraId, cameraInfo);
boolean flipHorizontal = cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT;
mGPUImage.setUpCamera(mCameraInstance, orientation, flipHorizontal, false);
}
/** A safe way to get an instance of the Camera object. */
private Camera getCameraInstance(int id) {
Camera c = null;
Log.e("Activity","Camera Instance " + id);
try {
c = mCameraHelper.openCamera(id);
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
private void releaseCamera() {
mCameraInstance.setPreviewCallback(null);
mCameraInstance.stopPreview();
mCameraInstance.release();
mCameraInstance= null;
}
}
}
EDIT:
SCreenshot of my camera: when i press the switch camera button, the back view stops and my front view starts in the corner.
i tested it in other device. The switchcamera feature is working perfectly.but, it is not working correctly in some devices.
This will surely fix your issue :
**How to switch**
public void switchCamera() {
releaseCamera();
mCameraId = (mCameraId + 1) % Camera.getNumberOfCameras();
**mGpuImageView.reInitLayout();**//the trick
prepareCamera();
}
**releaseCamera**
private void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
**prepareCamera**
your camera prepare method
**mGpuImageView.reInitLayout**
//Put this inside your GPUImageView.java class
public void reInitLayout() {
mGLSurfaceView.requestLayout();
mGPUImage.deleteImage();
}
Let me know if you face any further issue.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Set this for fill_parent and check.
Could you check this and paste screen
<ImageView
android:id="#+id/img_switch_camera"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center"
android:layout_weight="0.08"
android:src="#drawable/ic_switch_camera" />
It supose to change size for 300x300
I making a custom camera android application . I have added a button to switch between cameras in my activity . On clicking that button , my camera gets switched perfectly, But when i try to save the image through the callback ,My app crashes due to NullPointerException. Here is my code . Please help me.
Thank You in advance
Camera Activity Code
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraHandler surface_view;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
public static final String TAG="Aloo";
Bitmap bmp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
if(checkifCamera(this))
{
mCamera=getCameraInstance();
surface_view = new CameraHandler(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(surface_view);
}
else
{
Toast.makeText(this,"Sorry camera is not supported on your device",Toast.LENGTH_LONG).show();
}
}
private boolean checkifCamera(Context context)
{
if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
{
return true;
}
else {
return false;
}
}
public Camera getCameraInstance()
{
Toast.makeText(this,"Chrj",Toast.LENGTH_LONG).show();
Camera c=null;
try{
releaseCameraAndPreview();
c=Camera.open();
}
catch (Exception e)
{
Toast.makeText(this,"Print error"+e.getMessage(),Toast.LENGTH_LONG).show();
return c;
}
Toast.makeText(this,"Check this out "+c,Toast.LENGTH_LONG).show();
return c;
}
public void switchC(View view)//Function called to switch camera
{
surface_view.switchCamera();
mCamera=getCameraInstance();
}
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
#Override
protected void onPause() {
super.onPause();
try
{
// release the camera immediately on pause event
//releaseCamera();
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void takePH(View view)
{
int toRotate=0;
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int displayRotation = display.getRotation();
switch (displayRotation) {
case Surface.ROTATION_0: toRotate=90; break;
case Surface.ROTATION_90: break;
case Surface.ROTATION_180: break;
case Surface.ROTATION_270: toRotate=270; break;
}
Toast.makeText(this,"Rotation "+toRotate,Toast.LENGTH_LONG).show();
Camera.Parameters params = mCamera.getParameters();
params.set("rotation",270);
mCamera.setParameters(params);
mCamera.takePicture(null,null,mPicture);
}
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());
}
Toast.makeText(CameraActivity.this,"Image saves successfully", Toast.LENGTH_LONG).show();
}
};
/** 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), "Fotos");
// 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;
}
}
My Custom Camera Handler
public class CameraHandler extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera=null;
public int currentCameraID=0;
public CameraHandler(Context context,Camera camera) {
super(context);
mCamera=camera;
mHolder=getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
Camera.Parameters p = mCamera.getParameters();
}
catch (IOException e)
{
Log.d("--DS", "Error setting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
fixOr();
if(mHolder.getSurface()==null)
{
return;
}
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
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("--DS", "Error starting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public void fixOr()
{
mCamera.stopPreview();
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
public void switchCamera() {
mCamera.stopPreview();
mCamera.release();
if(currentCameraID==Camera.CameraInfo.CAMERA_FACING_BACK)
{
currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else
{
currentCameraID=Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera=Camera.open(currentCameraID);
fixOr();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
}
I believe my app crashes because when I switch the camera mCamera becomes null. How can I fix that ?
The Error I am getting is:
java.lang.IllegalStateException: Could not execute method of the activity
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'android.hardware.Camera$Parameters android.hardware.Camera.getParameters()'
on a null object reference
After listening to Rami s comment i changed my code in 2 places
1.)
public void switchC(View view)//Function called to switch camera
{
mCamera=surface_view.switchCamera();
}
2.) Switch Camera function
public Camera switchCamera() {
mCamera.stopPreview();
mCamera.release();
if(currentCameraID==Camera.CameraInfo.CAMERA_FACING_BACK)
{
currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else
{
currentCameraID=Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera=Camera.open(currentCameraID);
fixOr();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
} return mCamera;
I want capture image from android camera but without user knowledge.
public class Capture extends Activity {
public Uri fileUri;
public String filepath1="";
public static final int DONE=1;
public static final int NEXT=2;
public static final int PERIOD=0;
private Camera camera;
private int cameraId;
private Timer timer;
public static final int MEDIA_TYPE_IMAGE = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.autocapture);
try
{
cameraMethod();
}
catch(Exception e)
{
Log.e("camera","Not",e);
}
}
public void cameraMethod()
{
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
} else {
android.hardware.Camera.CameraInfo info =new android.hardware.Camera.CameraInfo();
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
} else {
safeCameraOpen(cameraId);
}
}
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
SurfaceView view = new SurfaceView(this);
try {
camera.setPreviewDisplay(view.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
Camera.Parameters params = camera.getParameters();
params.setJpegQuality(100);
camera.setParameters(params);
timer=new Timer(getApplicationContext(),threadHandler);
timer.execute();
}
////////////////////////////////////thread Handler///////////////////////////////////////
private Handler threadHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case DONE:
// Trigger camera callback to take pic
camera.takePicture(null, null, photoCallback);
break;
case NEXT:
timer=new Timer(getApplicationContext(),threadHandler);
timer.execute();
break;
}
}
};
Camera.PictureCallback mCall = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
//decode the data obtained by the camera into a Bitmap
//display.setImageBitmap(photo);
Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0, data.length);
Message.obtain(threadHandler, Capture.NEXT, "").sendToTarget();
//Log.v("MyActivity","Length: "+data.length);
}
};
private int findFrontFacingCamera() {
int cameraId = 0;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 1; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
}
else
{
break;
}
}
return cameraId;
}
#Override
protected void onPause() {
if (timer!=null){
timer.cancel(true);
}
releaseCamera();
super.onPause();
}
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCamera();
camera = Camera.open(id);
qOpened = (camera != null);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
return qOpened;
}
private void releaseCamera() {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(fileUri);
imageFileOS.write(data);
imageFileOS.flush();
imageFileOS.close();
Toast.makeText(Capture.this, "Image saved: " + fileUri, Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String sadf = fileUri.toString();
Log.e("File url for sd card", ""+sadf);
Intent myintent1=new Intent(Capture.this,MailSenderGmail1.class);
myintent1.putExtra("uris", sadf);
myintent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myintent1);
finish();
}
};
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){
// Check that the SDCard is mounted
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "TheftImageCapture");
// Create the storage directory(MyCameraVideo) if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraVideo", "Failed to create directory Theft Image.");
return null;
}
}
java.util.Date date= new java.util.Date();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(date.getTime());
File mediaFile;
if(type == MEDIA_TYPE_IMAGE) {
// For unique video file name appending current timeStamp with file name
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
}
TimerThread Class:
public class Timer extends AsyncTask<Void, Void, Void> {
Context mContext;
private Handler threadHandler;
public Timer(Context context,Handler threadHandler) {
super();
this.threadHandler=threadHandler;
mContext = context;
}
#Override
protected Void doInBackground(Void...params) {
try {
Thread.sleep(Capture.PERIOD);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message.obtain(threadHandler, Capture.DONE, "").sendToTarget();
return null;
}
}
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.
I am trying to make an app that records a video using the camera app, and then saves that video on SD card so I can play it. I have some code but I'm lost on how to continue as I'm a beginner in Android.
My Activity:
public class Camcorder extends Activity {
private CamcorderView camcorderView;
private boolean recording = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//irrelevant code
camcorderView = (CamcorderView) findViewById(R.id.camcorder_preview);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
{
if (recording) {
camcorderView.stopRecording();
finish();
} else {
recording = true;
camcorderView.startRecording();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}
CamcorderView class:
public class CamcorderView extends SurfaceView implements
SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
String outputFile = "/sdcard/default.mp4";
public CamcorderView(Context context, AttributeSet attrs) {
super(context, attrs);
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
// recorder.setVideoSize(480, 320);
// recorder.setVideoFrameRate(15);
// recorder.setMaxDuration(10000);
}
public void surfaceCreated(SurfaceHolder holder) {
recorder.setOutputFile(outputFile);
recorder.setPreviewDisplay(holder.getSurface());
if (recorder != null) {
try {
recorder.prepare();
} catch (IllegalStateException e) {
Log.e("IllegalStateException", e.toString());
} catch (IOException e) {
Log.e("IOException", e.toString());
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void setOutputFile(String filename)
{
outputFile = filename;
recorder.setOutputFile(filename);
}
public void startRecording()
{
recorder.start();
}
public void stopRecording()
{
recorder.stop();
recorder.release();
}
}
Well it's very simple to record videos in android by using this simple code
First on a button click simple start an Intent
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takeVideoIntent, CAMERA_REQUEST_CODE_VEDIO);
}
then in onActivityResult method
Uri videoUri = data.getData();
path = Utils.getRealPathFromURI(videoUri, this);
manageVideo(path); //Do whatever you want with your video
and finally add permissions to the manifest
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
Hope it help others who are looking for help :)
Thanks
Uri contentUri="You record video uri";
try {
Date date= new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", date);
String Video_DIRECTORY = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + getString(R.string.app_name) + "/video/";
File storeDirectory = new File(Video_DIRECTORY);
try {
if (storeDirectory.exists() == false) {
storeDirectory.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
File storeDirectory12 = new File(storeDirectory,date+".mp4");
InputStream inputStream = getContentResolver().openInputStream(contentUri);
FileOutputStream fileOutputStream = new FileOutputStream(storeDirectory12);
copyStream(inputStream, fileOutputStream);
fileOutputStream.close();
inputStream.close();
} catch (FileNotFoundException e) {
Log.e("Exception", "" + e);
} catch (IOException e) {
Log.e("Exception", "" + e);
}
// Put this code in ,on Button click or in onCreate to Capture the Video
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
videoUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
////////////////////////////////
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type){
// Check that the SDCard is mounted
File mediaStorageDir = new File(Environment.getExternalStorageDirectory() +"/YourDirectoryName");
// Create the storage directory(MyCameraVideo) if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraVideo", "Failed to create directory MyCameraVideo.");
return null;
}
}
// Create a media file name
// For unique file name appending current timeStamp with file name
java.util.Date date= new java.util.Date();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date.getTime());
File mediaFile;
if(type == MEDIA_TYPE_VIDEO) {
// For unique video file name appending current timeStamp with file name
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// After camera screen this code will execute
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE ) {
if (resultCode == RESULT_OK) {
videoUri = data.getData();
// Video captured and saved to fileUri specified in the Intent
// Toast.makeText(getActivity(), "Video saved to: " +data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
Toast.makeText(getActivity(), "User cancelled the video capture.", Toast.LENGTH_LONG).show();
} else {
// Video capture failed, advise user
Toast.makeText(getActivity(), "Video capture failed.", Toast.LENGTH_LONG).show();
}
}
}