androidvideoservicebackgroundcamera

Bug recording videos Android


I'm trying to record many videos of 30 seconds in background but, after 20 or 30 videos my service which is stopping and launching the process to record go slowly.

I have try with a service in the same process and the problem was the same.

My video handler:

@Override
public void onCreate() {
    super.onCreate();
    isRunning = true;
    idAlerta = Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "");
    videoCount = 1;
    mIntentRecorder = new Intent(VideoHandlerService.this, RecorderService.class);
    mIntentSend = new Intent(VideoHandlerService.this, SendVideoService.class);
    updateVideoTime();
    mIntentRecorder.putExtra(Constants.VIDEO_TIME, videoTime);
    mIntentRecorder.putExtra(Constants.ID_ALERTA_SERVICE, idAlerta);
    mIntentRecorder.putExtra(Constants.COUNT_ALERTA, videoCount);
    startService(mIntentRecorder);
    newVideo();
}
public void newVideo() {
    Common.log("new Video");
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            videoCount++;
            startNewVideo();
            if (videoCount == 2)
                sendVideo(4000);
        }
    }, videoTime + 2000);

}


public void startNewVideo() {
    final Intent intentRecorder = new Intent(VideoHandlerService.this, RecorderService.class);
    intentRecorder.putExtra(Constants.VIDEO_TIME, videoTime);
    Common.log("idAlerta " + idAlerta);
    intentRecorder.putExtra(Constants.ID_ALERTA_SERVICE, idAlerta);
    intentRecorder.putExtra(Constants.COUNT_ALERTA, videoCount);
    stopService(intentRecorder);
    if (Common.getStorage().getBoolean(Constants.RECORDER_ACTIVE, false)) {
        if (Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "") != null && Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "").length() > 0) {
              
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    Common.log("Start service recorder");
                    startService(intentRecorder);
                    newVideo();
                }
            }, 5000);
        }
    } else
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startNewVideo();
            }
        }, 5000);
}

And this is the process to record:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Common.log("onStartCommand");
    if (intent != null && ((Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "") != null && Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "").length() > 0))) {
        windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        mLayoutParams = new WindowManager.LayoutParams(
                1, 1,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT
        );
        mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        //Cojo Información del videohandler
        Common.log("Intent distinto de null");
        mVideoTime = intent.getIntExtra(Constants.VIDEO_TIME, 15000);
        mIdAlerta = intent.getStringExtra(Constants.ID_ALERTA_SERVICE);
        mVideoCount = intent.getIntExtra(Constants.COUNT_ALERTA, 1);
        Common.log("Video time" + mVideoTime);
        Common.getStorage().putBoolean(Constants.RECORDER_ACTIVE, true);
        initRecording();
    }
    return START_NOT_STICKY;
}

public void initRecording() {
    Common.log("INIT RECORDING IN");
    surfaceView = new SurfaceView(this);
    windowManager.addView(surfaceView, mLayoutParams);
    surfaceView.getHolder().addCallback(this);
    Common.log("INIT RECORDING OUT");
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}


@Override
public void onDestroy() {
    Common.log("onDestroy Video");
    PreferenceHelper preferenceHelper = PreferenceHelper.newInstance(RecorderService.this, Constants.USER_PREFERENCES);
    preferenceHelper.setBoolean(Constants.IS_RECORDING, false);
    try {
        camera.setPreviewCallback(null);
    } catch (Exception e){
        Common.log("error setPrevieCallback" + (e.getMessage() != null ? e.getMessage() : "sin mensaje"));
    }

    try {
        muteSounds(false);
    } catch (Exception e) {
        Common.log(e.getMessage());
    }
    try {
        Common.log("media recorder stop");
        mediaRecorder.stop();
        Common.log("media recorder reset");
        mediaRecorder.reset();
        Common.log("media recorder release");
        mediaRecorder.release();
        Common.log("media camera lock");
        camera.lock();
        Common.log("media camera release");
        camera.release();
    } catch (Exception e) {
        
    }

    Common.log("onDestroy Video");
    Common.getStorage().putBoolean(Constants.RECORDER_ACTIVE, false);
    RecorderService.super.onDestroy();
    System.exit(0);
}


@Override
public void surfaceCreated(SurfaceHolder holder) {
    mSurfaceHolder = holder;
    Common.log("SurfaceCreated");
    try {
        try {
            muteSounds(true);
        } catch (Exception e) {
            Common.log(e.getMessage());
        }
        Common.log("CAMERA OPEN 1");
        try {
            camera = Camera.open(1);
        } catch (RuntimeException e) {
            Common.log(e.getMessage());
        }
        Common.log("CAMERA OPEN 2");

        ///////////////////////////
        mCamCoderProfile = CamcorderProfile.get(1, CamcorderProfile.QUALITY_LOW);
        mCamCoderProfile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;
        mCamCoderProfile.audioCodec = MediaRecorder.AudioEncoder.AAC;
        ///////////////////////////

        startRecorder();

    } catch (Exception e) {
        if (e.getMessage() != null)
            Common.log(e.getMessage());
    }
}


public void muteSounds(boolean mute) {
    Common.log("MUTE SOUNDS IN");
    AudioManager mgr = ((AudioManager) getSystemService(Context.AUDIO_SERVICE));
    mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (mute) {
            mgr.adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_MUTE, 0);
            mgr.adjustVolume(AudioManager.ADJUST_MUTE, 0);
            mgr.adjustVolume(AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE, 0);
        } else {
            mgr.adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_UNMUTE, 0);
            mgr.adjustVolume(AudioManager.ADJUST_UNMUTE, 0);
        }
    } else {
        mgr.setStreamMute(AudioManager.STREAM_SYSTEM, mute);
        mgr.setStreamMute(AudioManager.STREAM_MUSIC, mute);
        if (mute) {
            mOlderVolumen = mgr.getStreamVolume(AudioManager.STREAM_RING);
            mgr.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
        } else
            mgr.setStreamVolume(AudioManager.STREAM_RING, mOlderVolumen, 0);

        mgr.adjustVolume(AudioManager.ADJUST_LOWER, 0);
    }
    Common.log("MUTE SOUNDS OUT");
}


public void startRecorder() {
    mediaRecorder = new MediaRecorder();
    camera.unlock();
    mediaRecorder.setCamera(camera);
    mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mediaRecorder.setProfile(mCamCoderProfile);
    videoFile = new File(Environment.getExternalStorageDirectory() + "/" +
            "wbunker_" + mIdAlerta + "_" + mVideoCount + ".mp4");
    Common.log("Video rercorder name file " + videoRecording);
    mediaRecorder.setOutputFile(videoFile.getPath());
    mediaRecorder.setOrientationHint(270);
    try {
        Common.log("mediaRecorder prepare");
        mediaRecorder.prepare();
        Common.log("mediaRecorder prepare");
    } catch (Exception e) {
    }
    Common.log("mediaRecorder start");
    mediaRecorder.start();
    Common.log("mediaRecorder start");
    Common.log("Estoy grabando macho");
}

When I try to stop the service the services stops, but the camera isn't released even killing the app. Can someone help me? Thanks in advance.


Solution

  • Finally the key was use PowerManager, if you are going to use it, don't forget to release it!

    private fun lock() {
        log("lock")
        var powerManager: PowerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        powerWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, "WakeLock-Manager")
        powerWakeLock.acquire()
    
        var wifiManger: WifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        wifiWakeLock = wifiManger.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "WifiLock-Manger")
        wifiWakeLock.acquire()
        log("lock")
    }