How to create MACRO'S in android - android

I want to create macro app in Android, which will help user to set the requirement to do schduled tasks for the user like scheduled video recording like (camstudio in windows OS),GPS,Bluetooth,Camera control. I know have to ROOT the device to do these things..
Advance Features :
• Shake the device to upload the last photo to Facebook.
• Turn on Wi-fi or Data connection when you launch a particular app (and off again when closed).
• Respond to an incoming SMS by sending your current location.
• Toggle the power button to tell you the time (e.g. when its in your pocket).
• Use NFC tags to configure the device (turn on bluetooth, set volume etc).
Actually I have code for doing all the things except scheduled video recording.
Can you guys help me in that part only..
Cheers :)

You don't actually have to Root the device to have these features. What you need is a Service which implements various listeners such as :
SensorListener to detect shaking of device.
BroadcastReceiver to fire when SMSs are received.
Or Handle WiFi.
Edit 1 :
public class RecorderService extends Service {
private static final String TAG = "RecorderService";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private static Camera mServiceCamera;
private boolean mRecordingStatus;
private MediaRecorder mMediaRecorder;
#Override
public void onCreate() {
mRecordingStatus = false;
//mServiceCamera = CameraRecorder.mCamera;
mServiceCamera = Camera.open();
mSurfaceView = CameraRecorder.mSurfaceView;
mSurfaceHolder = CameraRecorder.mSurfaceHolder;
super.onCreate();
if (mRecordingStatus == false)
startRecording();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
stopRecording();
mRecordingStatus = false;
super.onDestroy();
}
public boolean startRecording(){
try {
Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
//mServiceCamera = Camera.open();
Camera.Parameters params = mServiceCamera.getParameters();
mServiceCamera.setParameters(params);
Camera.Parameters p = mServiceCamera.getParameters();
final List<Size> listSize = p.getSupportedPreviewSizes();
Size mPreviewSize = listSize.get(2);
Log.v(TAG, "use: width = " + mPreviewSize.width
+ " height = " + mPreviewSize.height);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
mServiceCamera.setParameters(p);
try {
mServiceCamera.setPreviewDisplay(mSurfaceHolder);
mServiceCamera.startPreview();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
mServiceCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mServiceCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mMediaRecorder.setOutputFile("/sdcard/video.mp4");
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStatus = true;
return true;
} catch (IllegalStateException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
} catch (IOException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
}
}
public void stopRecording() {
Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
try {
mServiceCamera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mMediaRecorder.stop();
mMediaRecorder.reset();
mServiceCamera.stopPreview();
mMediaRecorder.release();
mServiceCamera.release();
mServiceCamera = null;
}
}

You can try it with SpotRecorder (house4hack) code which contains a activity to start RecorderService service in background (we need to make view so that it will not be visible. this should be done in the service )
We can use the AlarmManager for setting the alarm of particular time,when alarm manger fires that time by using intent start your service again, same methode can be used for stopping your app.
no sure, but you can try to consider using WindowManager and call it from Service.
look at this failed attempt here.

Related

Can I use Android Camera in service without preview?

I have create a application in Android that using a camera I can measure out the distance between user's face to the phone screen.
Problem description:
Now I want to make it running background so that the feature is available while I am using other applications. It means I should open camera in service without preview, and process it in service.
What I did yet:
I referred some questions here
How to record video from background of application : Android
How to use Android Camera in Background?
Taking picture from camera without preview
API level 16
My Service File
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class RecorderService extends Service {
private static final String TAG = "RecorderService";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private static Camera mServiceCamera;
private boolean mRecordingStatus;
private MediaRecorder mMediaRecorder;
File path = android.os.Environment.getExternalStorageDirectory();
#Override
public void onCreate() {
Log.i(TAG,"onCreate");
mRecordingStatus = false;
//mServiceCamera = CameraRecorder.mCamera;
mServiceCamera = Camera.open(1);
mSurfaceView = MainActivity.mSurfaceView;
mSurfaceHolder = MainActivity.mSurfaceHolder;
super.onCreate();
if (mRecordingStatus == false)
startRecording();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.i(TAG,"onDestroy");
stopRecording();
mRecordingStatus = false;
super.onDestroy();
}
public boolean startRecording(){
Log.i(TAG,"startRecording");
try {
Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
//mServiceCamera = Camera.open();
Camera.Parameters params = mServiceCamera.getParameters();
mServiceCamera.setParameters(params);
Camera.Parameters p = mServiceCamera.getParameters();
final List<Size> listSize = p.getSupportedPreviewSizes();
Size mPreviewSize = listSize.get(2);
Log.v(TAG, "use: width = " + mPreviewSize.width
+ " height = " + mPreviewSize.height);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
mServiceCamera.setParameters(p);
try {
mServiceCamera.setPreviewDisplay(mSurfaceHolder);
mServiceCamera.startPreview();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
mServiceCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mServiceCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mMediaRecorder.setOutputFile(path+"/outputVideo.mp4");
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStatus = true;
return true;
} catch (IllegalStateException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
} catch (IOException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
}
}
public void stopRecording() {
Log.i(TAG,"stopRecording");
Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
try {
mServiceCamera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
mMediaRecorder.stop();
}catch (Exception ignored)
{
}
mMediaRecorder.reset();
mMediaRecorder.release();
mServiceCamera.stopPreview();
mServiceCamera.release();
mServiceCamera = null;
}
}
You can refer this Question, which discuss how to do video record in the service. The steps to capture image is same as it.
To achieve your requirement, you may need:
Get camera instance in your service. Check this Official Guideline.
Setup your camera parameters. Use the APIs like Camera.getParameters(), Camera.setParameters(), Camera.Parameters.setPictureSize(int with, int height) and Camera.Parameters.setPictureFormat(int format) to do so.
Prepare a file used to store the image. You need to implement Camera.PictureCallback to do so.
Call Camera.startPreview() before you takeing picutre. If you don't call this function before taking picture, you will get exception. (Note: You don't need to do Camera.setPreviewdisplay(SurfaceHolder display) first.)
Call camera.takePicture() in your service. Then you can get the captured image stored on the file you specified.
After it work, don forget to maintain the resource durning lifecycle to acquire/release camera correctly.
Here is my sample code on Github, it is also mentioned in the comment.

android camera hardware control failure

Hi I am trying to work on a hardware camera control in android,
I am able to get the preview of the camera on the surface view,
however I am unable to record any video, as on starting the video recording I get the following error:
Media server died
Camera server died
ICamera died
error 100
the code for capture is as under
public void onCaptureClick(View view){
if(!isRecording)
new MediaPrepareTask().execute(null,null,null);
else{
mMediaRecorder.stop();
releaseMediaRecorder();
mCamera.lock();
setCaptureButtonText("Start");
isRecording = false ;
releaseCamera();
}
}
This is the media prepare task
class MediaPrepareTask extends AsyncTask<Void, Void, Boolean>{
#Override
protected Boolean doInBackground(Void... arg0) {
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
Log.i(TAG,"Media recording started");
isRecording = true;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result){
if(!result){
MainActivity.this.finish();
}
setCaptureButtonText("Stop");
}
}
This is where I set the property for recording
private boolean prepareVideoRecorder(){
Log.i(TAG,"Starting to prepare");
Camera.Parameters parameters = mCamera.getParameters() ;
Log.i(TAG,"Got Property");
List<Camera.Size> mSupportedPreviewSize = parameters.getSupportedPreviewSizes();
Camera.Size optimalSize = CameraHelper.getOptimalPreviewSize(mSupportedPreviewSize,
mPreview.getWidth(), mPreview.getHeight());
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
profile.videoFrameWidth = optimalSize.width ;
profile.videoFrameHeight = optimalSize.height ;
parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
mCamera.setParameters(parameters);
Log.i(TAG,"Set Parameters");
try{
// // mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
mCamera.setPreviewDisplay(mPreview.getHolder());
}catch(IOException iOEx){
iOEx.printStackTrace();
Log.e(TAG, "Failed to set preview display ");
return false ;
}
////////////////////////////////now for the media recorder ///////////////////////
mMediaRecorder = new MediaRecorder();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
Log.i(TAG,"Set camera for recorder");
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
mMediaRecorder.setProfile(profile);
Log.i(TAG,CameraHelper.getOutputMediaFile(CameraHelper.MEDIA_TYPE_VIDEO).toString());
mMediaRecorder.setOutputFile(CameraHelper.getOutputMediaFile(
CameraHelper.MEDIA_TYPE_VIDEO).toString());
// END_INCLUDE (configure_media_recorder)
// Step 5: Prepare configured MediaRecorder
Log.i(TAG,"Set the ouptut format");
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
Log.i(TAG,"All is well");
return true;
}
this is for anyone reading the question
the issue is with the surface to be added to the media recorder as well,
just add the surface to the media recorder and it works

play video immediately after recording on android app

I am developing an app which should record a video of Maximum limit one minute, and saving it in gallery and then right after it saves it should start playing automatically.
Following is my code.
public class MainActivity extends Activity {
private Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
Button myButton;
SurfaceHolder surfaceHolder;
boolean recording;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recording = false;
setContentView(R.layout.main);
//Get Camera for preview
myCamera = getCameraInstance();
if(myCamera == null){
Toast.makeText(MainActivity.this,
"Fail to get Camera",
Toast.LENGTH_LONG).show();
}
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
myButton = (Button)findViewById(R.id.mybutton);
myButton.setOnClickListener(myButtonOnClickListener);
Log.i("Camera !Error", "Cameray ka koi masla ni Agay chcek karo");
}
Button.OnClickListener myButtonOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(recording){
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
//Exit after saved
finish();
}else{
//Release Camera before MediaRecorder start
releaseCamera();
if(!prepareMediaRecorder()){
Toast.makeText(MainActivity.this,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
mediaRecorder.start();
recording = true;
myButton.setText("STOP");
Log.i("Camera !Error", "Record to stop");
}
}};
private Camera getCameraInstance(){
// TODO Auto-generated method stub
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
Log.i("Camera Error", "Camera Not Found");
}
Log.i("Camera Error", "Camera Found");
return c; // returns null if camera is unavailable
}
private boolean prepareMediaRecorder(){
myCamera = getCameraInstance();
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mediaRecorder.setOutputFile("/sdcard/myvideo2.3gp");
mediaRecorder.setMaxDuration(10000); // Set max duration 10 sec.
mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
Log.i("Camera Error", "Media Recorder is ready");
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
#Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder(){
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
myCamera.lock(); // lock camera for later use
}
Log.i("Media Recorder", "Media Recorer Released");
}
private void releaseCamera(){
if (myCamera != null){
myCamera.release(); // release the camera for other applications
myCamera = null;
}
Log.i("Camera Recorder", "Camera Released");
}
public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int weight,
int height) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
}
my main.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/videoview"
android:layout_width="720px"
android:layout_height="480px"/>
<Button
android:id="#+id/mybutton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="REC"
android:textSize="12sp"/>
</LinearLayout>
On button click recording starts and on click again, it stops and exits using
finish() for this purpose. Here i want that instead of exiting the recorded video should start.
Hope i managed to clearly explain my question.

Android: video is stretched during preview but not during recording (on some devices)

I created an Android video Activity and I cannot for the life of me figure out why my preview video is stretched horizontally. I have hard-coded the values (just for the purpose of debugging) and it is still not correct. It looks OK when I press record but it goes back to being stretched during preview.
If I manually set the aspect ratio to something smaller (depends on the device but I don't see any logical correlation) it works. For example, on the SIII if I set it to 1.5 it works like a charm. This does not make sense to me.
Also, I noticed that surfaceCreated is never being called. I don't know if this is related but I thought it was worth noting.
I found a lot of similar answers but nothing worked for me.
UPDATE: It is stretched on all devices but is only corrected when you press record on certain devices (Motorola Razr HD and Galaxy Tab 2) but not on others (Samsung Note and Samsung SIII).
Here is my code:
(FYI, it crashes with a NPE on the camera when you hit record. It works OK in my app but I had to remove some code before I could post it here.)
public class Video extends Activity implements SurfaceHolder.Callback
{
VideoView videoView;
MediaRecorder recorder;
Camera camera;
SurfaceHolder holder;
MediaPlayer player;
private Handler handler;
Size maxPreviewSize;
private boolean finishing;
private boolean firstRun;
private boolean isRecording;
private Object file;
public static final int MEDIA_TYPE_VIDEO = 2;
#Override
public void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.video_layout);
releaseCameraAndPreview();
videoView = (VideoView) findViewById(R.id.videoView);
}
//******************************** onPause() *************************************
/**
* Task: Releases the camera and nulls it out when the Activity is paused
*/
#Override
public void onPause()
{
super.onPause();
finishing = true;
// Releases the Media Recorder object so that it can be used the next time the app
// is launched.
releaseMediaRecorder();
// Releases the camera so that it can be used after the app is paused. Otherwise
// the camera will not be available to other apps or this app when resumed.
releaseCamera();
}
// ***************************** onDestroy() ****************************************
/**
* task: called by the system when destroying this activity. stop all
* threads, stop recording comair, explicity recycle all bitmap images from
* each row, and remove all callbacks from each view, to free up the memory.
* Request the garbage collector to run.
*/
#Override
protected void onDestroy()
{
finishing = true;
super.onDestroy();
}// end onDestroy()
//************************** onWindowFocusChanged() ********************************
/** Task: layout data cannot be accessed from onCreate, so use this method to load anything
* that has layout data.
*/
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
LayoutParams params = (LayoutParams) videoView.getLayoutParams();
params.width = 960;
params.height = 540;
videoView.setLayoutParams(params);
if(finishing)
{
Log.d("Video", "oWFC, finishing is true");
return;
}
firstRun = false;
// Use mCurrentCamera to select the camera desired to safely restore
// the fragment after the camera has been changed
boolean opened = safeCameraOpen();
// Install a SurfaceHolder that will give information about the VideoView
installHolder();
createPreview();
}//end onWindowFocusChanged()
//******************************** installHolder() *************************************
/**
* Task: Install a SurfaceHolder. Callback so we get notified when the
* underlying surface is created and destroyed.
*/
private void installHolder()
{
holder = videoView.getHolder();
holder.setFixedSize(960, 540);
holder.addCallback(this);
}
//*************************** surfaceCreated() ********************************
/**
* Task: Connects the camera to the Preview and starts the Preview in the VideoView
*
* #param SurfaceHolder the holder that holds the callback for the camera so that we
* know when it is stopped and started
*/
#Override
public void surfaceCreated(SurfaceHolder holder)
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ surfaceCreated() ////////////////////////");
}
//*************************** createPreview() ********************************
/**
* Task: Creates the preview by setting the VideoView to display the images from the
* camera.
*
* #param SurfaceHolder the holder that holds the callback for the camera so that we
* know when it is stopped and started
*/
private void createPreview()
{
try
{
// STEP 2: Connect Preview - Prepare a live camera image preview by connecting a
// SurfaceView to the camera using Camera.setPreviewDisplay().
camera.setPreviewDisplay(holder);
Rect r = holder.getSurfaceFrame();
Log.e("Video", "rectangle (holder): " + r.width() + "," + r.height());
// STEP 3: Start Preview - Call Camera.startPreview() to begin displaying the
// live camera images.
camera.startPreview();
}
catch (IOException e)
{
Log.d("Video", "Could not start the preview");
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ surfaceChanged() ////////////////////////");
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ surfaceDestroyed() ////////////////////////");
// camera.setPreviewCallback(null);
// camera.stopPreview();
// handler = null;
}
//*************************** safeCameraOpen() **********************************
/**
* Task: opens the first back-facing camera. Checks to see if the camera is open before
* attempting to open it
*
* #return Whether or not the camera was opened
*/
// TODO: choose the camera to open
private boolean safeCameraOpen()
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ safeCameraOpen() ////////////////////////");
boolean opened = false;
try
{
releaseCameraAndPreview();
camera = Camera.open();
opened = (camera != null);
Camera.Parameters param = camera.getParameters();
Log.e("Video", "Camera.Parameters: " + param.flatten());
List<Size> previewSize = param.getSupportedPreviewSizes();
String str = "";
maxPreviewSize = previewSize.get(0);
for(Size s:previewSize)
{
if(s.width > maxPreviewSize.width && s.width > s.height)
{
maxPreviewSize = s;
}
str += s.width + "x" + s.height+ "\t";
}
Log.e("Video", "previewSizes:\t" + str);
}
catch (Exception e)
{
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
if(opened)
Log.d("Video", "I haz camera!!!!!!!");
else
Log.d("Video", "I can haz camera??????? Noooooo!!!!");
return opened;
}
//********************* releaseCameraAndPreview() **************************
/**
* Task: releases the camera and the preview so that other apps can use the resources and to
* avoid a memory leak
*
*/
private void releaseCameraAndPreview()
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ releaseCameraAndPreview() ////////////////////////");
if (camera != null)
{
// Call stopPreview() to stop updating the preview surface.
camera.stopPreview();
// Important: Call release() to release the camera for use by other applications.
// Applications should release the camera immediately in onPause() (and re-open() it in
// onResume()).
camera.release();
camera = null;
}
}
//*************************** getCameraInstance() ************************************
/**
* Task: A safe way to get the instance of a Camera object
*
* #return Returns the camera or null if a camera is unavailable
*/
public Camera getCameraInstance()
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ getCameraInstance() ////////////////////////");
Camera c = null;
try
{
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e)
{
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private void releaseMediaRecorder()
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ releaseMediaRecorder() ////////////////////////");
if (recorder != null)
{
recorder.reset(); // clear recorder configuration
recorder.release(); // release the recorder object
recorder = null;
camera.lock(); // lock camera for later use
}
}
private void releaseCamera()
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ releaseCamera() ////////////////////////");
if (camera != null)
{
camera.release(); // release the camera for other applications
camera = null;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
///////////////// Set up MediaRecorder ////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
private void stopRecording()
{
// stop recording and release camera
// recorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
camera.lock(); // take camera access back from MediaRecorder
camera.stopPreview();
releaseCamera();
boolean opened = safeCameraOpen();
createPreview();
// inform the user that recording has stopped
isRecording = false;
}
private boolean prepareVideoRecorder()
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ prepareVideoRecorder() ////////////////////////");
recorder = new MediaRecorder();
recorder.setOnInfoListener(new MediaRecorder.OnInfoListener()
{
#Override
public void onInfo(MediaRecorder recorder, int what, int extra)
{
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED)
{
Log.e("VIDEOCAPTURE","Maximum Duration Reached");
stopRecording();
}
}
});
recorder.setOnErrorListener(new MediaRecorder.OnErrorListener()
{
#Override
public void onError(MediaRecorder recorder, int what, int extra)
{
Log.e("Video", "onErrorListener\nwhat:" + what + "extra: " + extra);
}
});
// Step 1: Unlock and set camera to recorder
camera.unlock();
recorder.setCamera(camera);
// Step 2: Set sources
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set output format and encoding (for versions prior to API Level 8)
// recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
// recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
// recorder.setVideoSize(maxPreviewSize.width, maxPreviewSize.height);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
CamcorderProfile cp;
Log.d("Video", "setProfile QUALITY_HIGH");
cp = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
Log.e("Video", "CamcorderProfile.QUALITY_HIGH: " + "cp.quality:" + cp.quality
+ ", cp.videoFrameWidth:" + cp.videoFrameHeight
+ ", cp.videoFrameWidth:" + cp.videoFrameWidth);
recorder.setProfile(cp);
recorder.setVideoSize(960, 540);
// recorder.setVideoSize(maxPreviewSize.width, maxPreviewSize.height);
// recorder.setVideoSize(cp.videoFrameWidth, cp.videoFrameHeight);
recorder.setMaxDuration(60000);
// Step 4: Set output file
// file = getOutputMediaFile(MEDIA_TYPE_VIDEO);
//
// if(file != null)
// {
// recorder.setOutputFile(file.toString());
// }
// Step 5: Set the preview output
recorder.setPreviewDisplay(videoView.getHolder().getSurface());
// Step 6: Prepare configured recorder
try
{
recorder.prepare();
}
catch (IllegalStateException e)
{
Log.d("Video", "IllegalStateException preparing recorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
catch (IOException e)
{
Log.d("Video", "IOException preparing recorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
private void releaseMediaPlayer()
{
player.stop();
player.release();
player = null;
}
public void onRecordClicked(View v)
{
if (isRecording)
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ onRecordClicked() - stop ////////////////////////");
stopRecording();
}
else
{
Log.d("Video", "\\\\\\\\\\\\\\\\\\\\\\\\ onRecordClicked() - start ////////////////////////");
// initialize video camera
if (prepareVideoRecorder())
{
Log.d("Video", "prepareVideoRecorder - true");
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
recorder.start();
// inform the user that recording has started
isRecording = true;
}
else
{
// prepare didn't work, release the camera
releaseMediaRecorder();
releaseCamera();
}
}
}
}
Here is my XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/wholeDarnThing"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
tools:context=".Video" >
<VideoView
android:id="#+id/videoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>

Record Video in a Service

Is it possible to record video in a service, that is without setting the setPreviewDisplay?
I tried it on a HTC Desire, however it is throwing this info in the log,
MediaRecorder Prepare Failed: -1
CameraInput No surface is available for display
Is there some additional properties to be set?
I found this snippet somewhere. Not sure if it works for media recorder, but it was working reasonably well for camera.takePicture on HTC hero android 2.1-update1 (and simulator).
if (camera == null) {
Log.i(TAG, "Opening camera");
camera = Camera.open();
}
SurfaceView view = new SurfaceView(new DummyContext()); //You'll have to create your own class extending Context
camera.setPreviewDisplay(view.getHolder());
camera.startPreview();
//wait
Log.i(TAG, "Wait for cam");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Log.e(TAG, "Woken violently");
e.printStackTrace();
}
//take pic
Log.i(TAG, "Take pic");
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
I believe according to the docs
public final void setPreviewDisplay
(SurfaceHolder holder)
Since: API Level 1 Sets the Surface to
be used for live preview. A surface is
necessary for preview, and preview is
necessary to take pictures. The same
surface can be re-set without harm.
I know you are desiring to take video but, I take this to me any camera usage requires a surface.
public class RecorderService extends Service {
private static final String TAG = "RecorderService";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private static Camera mServiceCamera;
private boolean mRecordingStatus;
private MediaRecorder mMediaRecorder;
private File filefolder;
private String strphoto;
private File photo;
#Override
public void onCreate() {
mRecordingStatus = false;
//mServiceCamera = CameraRecorder.mCamera;
mServiceCamera = Camera.open();
mSurfaceView = CameraRecorder.mSurfaceView;
mSurfaceHolder = CameraRecorder.mSurfaceHolder;
super.onCreate();
if (mRecordingStatus == false)
startRecording();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
stopRecording();
mRecordingStatus = false;
super.onDestroy();
}
public boolean startRecording(){
try {
Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
//mServiceCamera = Camera.open();
Camera.Parameters params = mServiceCamera.getParameters();
mServiceCamera.setParameters(params);
Camera.Parameters p = mServiceCamera.getParameters();
final List<Size> listSize = p.getSupportedPreviewSizes();
Size mPreviewSize = listSize.get(2);
Log.v(TAG, "use: width = " + mPreviewSize.width
+ " height = " + mPreviewSize.height);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
mServiceCamera.setParameters(p);
try {
mServiceCamera.setPreviewDisplay(mSurfaceHolder);
mServiceCamera.startPreview();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
mServiceCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mServiceCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
filefolder=new File(android.os.Environment.getExternalStorageDirectory(),"Backgroundcamera/videos");
}
else
{
filefolder=RecorderService.this.getCacheDir();
}
if(!filefolder.exists())
filefolder.mkdirs();
strphoto = System.currentTimeMillis()+".mp4";
mMediaRecorder.setOutputFile(filefolder+"/"+strphoto);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStatus = true;
return true;
} catch (IllegalStateException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
} catch (IOException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
}
}
public void stopRecording() {
Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
try {
mServiceCamera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mMediaRecorder.stop();
mMediaRecorder.reset();
mServiceCamera.stopPreview();
mMediaRecorder.release();
mServiceCamera.release();
mServiceCamera = null;
}
}
and
start the service on a click listerner.

Categories

Resources