Android app video recording when screen off

后端 未结 1 678
有刺的猬
有刺的猬 2020-12-08 20:16

What I am trying to do is that make an app that can record video or audio while the screen is off. Either we start recording and then switch off the screen or the recorder s

相关标签:
1条回答
  • 2020-12-08 20:52

    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:

    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();
        }
    }
    

    (How can I capture a video recording on Android?)

    Again, put that code into a long running foreground service, as I explained earlier.

    If you need any more help, feel free to ask.

    ~Ruchir

    0 讨论(0)
提交回复
热议问题