Most of the time, when something needs to be done offline, it is done in a service
.
(www.slideshare.net)
Assuming you don't know what a service is, from the docs:
A Service is an application component representing either an
application's desire to perform a longer-running operation while not
interacting with the user or to supply functionality for other
applications to use. Each service class must have a corresponding
declaration in its package's AndroidManifest.xml. Services
can be started with Context.startService() and Context.bindService().
So basically, its just something that runs in the background, including when the screen is off. Now, all you have to do, is put your recording code in a service. You may face a problem that your service gets killed by the system, as the android docs specify:
Note this means that most of the time your service is running, it may
be killed by the system if it is under heavy memory pressure. If this
happens, the system will later try to restart the service. An
important consequence of this is that if you implement
onStartCommand() to schedule work to be done asynchronously or in
another thread, then you may want to use START_FLAG_REDELIVERY to have
the system re-deliver an Intent for you so that it does not get lost
if your service is killed while processing it.
In this case, you will need to add certain code to keep the service in the foreground and make sure that it doesn't get killed:
startForeground();//keeps service from getting destroyed.
The only problem that this could provide is a constant notification for the time that the service is alive.
You may also use startSticky()
:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
Now, say you are done recording. You can use:
stopSelf();
to stop the service, or:
Context.stopService();
This notification is not much of a problem though, because the screen is most likely off while the service is running. You can also customize your notification, and it is better for the user to know what is going on in the background.
Here's some sample recording code, from vanevery's answer here:
public class VideoCapture extends Activity implements OnClickListener, SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.main);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
private void initRecorder() {
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
recorder.setOutputFile("/sdcard/videocapture_example.mp4");
recorder.setMaxDuration(50000); // 50 seconds
recorder.setMaxFileSize(5000000); // Approximately 5 megabytes
}
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void onClick(View v) {
if (recording) {
recorder.stop();
recording = false;
// Let's initRecorder so we can record again
initRecorder();
prepareRecorder();
} else {
recording = true;
recorder.start();
}
}
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
}
Again, put that code into a long running foreground service, as I explained earlier.