Android后台录音服务
我需要在android上实现一个录音服务。我花了很多时间阅读有关服务的书籍,在安卓系统的背景下工作,但我还没有弄明白。这就是我到目前为止所做的:Android后台录音服务,android,service,Android,Service,我需要在android上实现一个录音服务。我花了很多时间阅读有关服务的书籍,在安卓系统的背景下工作,但我还没有弄明白。这就是我到目前为止所做的: 我首先实现了一个服务,该服务在onCreate上创建并维护一个AudioRecord实例 我对应用程序进行了子类化,并从应用程序的onCreate启动了服务 我在onResume上从MainActivity绑定到该服务,并在onPause上解除绑定 该服务的onBind的工作原理类似于androidsdk示例中的LocalService示例,这意味着我
我缺少什么?您根本不需要调用
startService
<代码>绑定服务将在必要时创建服务
。这两种方法适用于两种不同的用例
对评论的答复:
您的帖子没有提供需要调用startService
的用例。您询问为什么调用了两次onCreate
。它被调用两次,因为它被创建了两次。可能您没有从onStartCommand
返回START\u STICKY
,或者您正在代码的某个地方停止它。没有密码,所以这里没人可能知道。但是如果调用了两次onCreate
,则需要创建两次。根据您的描述,这两个调用很可能对应于对startService
和bindService
的调用。根据所提供的信息,我的答案与预期的一样正确,但感谢否决票。正确答案是
关于Dave的回答,我确实需要调用startService,因为当应用程序在后台时,录制应该能够继续,但如果我在某些活动的onCreate上使用bindService,那么我可能必须在其onDestroy上解除连接绑定,这将使服务停止运行(如果此活动是唯一与之绑定的活动
我总是可以从应用程序onCreate绑定到服务,但我什么时候才能解除绑定到它?即使我只在用户按下主活动时解除绑定,但这可能会导致泄漏。如果您想创建类似的录制应用程序 然后您需要使用IntentService而不是Service,因为IntentService在后台线程中运行
public class RecorderService extends Service implements SurfaceHolder.Callback {
private WindowManager windowManager;
private SurfaceView surfaceView;
private Camera camera = null;
private MediaRecorder mediaRecorder = null;
private String fileName = "";
private StopServiceBroadcast stopServiceBroadcast;
private String endRecordingDate;
private String endRecordingTime;
private SettingsModel settingsModel;
private Handler enableViewsHandler;
private Runnable runnable;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onCreate() {
settingsModel = SettingsModel.findById(SettingsModel.class, 1L);
setupSurfaceViewForRecording();
}
private void setupSurfaceViewForRecording() {
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
}
// Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback
windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
surfaceView = new SurfaceView(this);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
1, 1,
// WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
// WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
windowManager.addView(surfaceView, layoutParams);
surfaceView.getHolder().addCallback(this);
}
private void registerBroadcastToStopRec() {
stopServiceBroadcast = new StopServiceBroadcast();
IntentFilter filter = new IntentFilter("stop_recording_action");
registerReceiver(stopServiceBroadcast, filter);
}
// Method called right after Surface created (initializing and starting MediaRecorder)
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mediaRecorder = new MediaRecorder();
setupCameraSide();
// if (settingsModel.getCameraSide().equalsIgnoreCase("front") && !getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
// Toast.makeText(this, R.string.front_camera_is_not_available_, Toast.LENGTH_SHORT).show();
// if (SharedPreferenceUtility.getInstance().getBooleanPreference(PreferenceKeys.IS_APP_RUNNING))
// fabStartStopRec.setEnabled(true);
// this.stopSelf();
// return;
// } else if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
// Toast.makeText(this, R.string.back_camera_is_not_available_, Toast.LENGTH_SHORT).show();
// if (SharedPreferenceUtility.getInstance().getBooleanPreference(PreferenceKeys.IS_APP_RUNNING))
// fabStartStopRec.setEnabled(true);
// this.stopSelf();
// return;
// }
//______ check if camera is not available ___________
if (camera == null) {
if (settingsModel.getCameraSide().equals("front"))
Toast.makeText(this, R.string.front_camera_is_not_available_, Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, R.string.back_camera_is_not_available_, Toast.LENGTH_SHORT).show();
if (SharedPreferenceUtility.getPreference(this, PreferenceKeys.IS_APP_RUNNING, true))
fabStartStopRec.setEnabled(true);
this.stopSelf();
return;
}
notificationToShowRecordingStarted();
setupCameraParametersForRecording();
setupCameraOrientation();
setupAutoStopRecordingFactors();
setupRingingAndVibrationOnStartRec();
try {
//mCamera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
camera.unlock();
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
setupVideoQuality();
setupVideoStorage();
startRecording();
}
private void setupRingingAndVibrationOnStartRec() {
if (settingsModel.isRingsOnRecStarts()) {
Uri ringTuneUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.rec_start_sound);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), ringTuneUri);
r.play();
} else {
Camera.CameraInfo info = new Camera.CameraInfo();
if (info.canDisableShutterSound) {
camera.enableShutterSound(false);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// to mute shutter sound of camera
final AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);
mgr.setStreamSolo(AudioManager.STREAM_SYSTEM, true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!mgr.isStreamMute(AudioManager.STREAM_SYSTEM))
mgr.setStreamMute(AudioManager.STREAM_MUSIC, true);
}
} else {
}
}
if (settingsModel.isVibrateOnRecStarts()) {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else
v.vibrate(500);
}
}
private void setupVideoQuality() {
if (settingsModel.getCameraSide().equals("front")) {
if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT)
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
else
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P/*settingsModel.getVideoQuality()*/));/*hot fix 1*/
} else
mediaRecorder.setProfile(CamcorderProfile.get(settingsModel.getVideoQuality()));
// if (settingsModel.getCameraSide().equals("front") &&
// (settingsModel.getVideoQuality() == CamcorderProfile.QUALITY_HIGH || settingsModel.getVideoQuality() == CamcorderProfile.QUALITY_1080P)) {
// mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
// } else
// mediaRecorder.setProfile(CamcorderProfile.get(settingsModel.getVideoQuality()));
}
private int getVideoQualityWRTCameraCapacity(int videoQuality) {
switch (videoQuality) {
case CamcorderProfile.QUALITY_480P:
return CamcorderProfile.QUALITY_480P;
case CamcorderProfile.QUALITY_CIF:
return CamcorderProfile.QUALITY_CIF;
case CamcorderProfile.QUALITY_QCIF:
return CamcorderProfile.QUALITY_QCIF;
case CamcorderProfile.QUALITY_QVGA:
return CamcorderProfile.QUALITY_QVGA;
case CamcorderProfile.QUALITY_LOW:
return CamcorderProfile.QUALITY_LOW;
case CamcorderProfile.QUALITY_TIME_LAPSE_480P:
return CamcorderProfile.QUALITY_TIME_LAPSE_480P;
case CamcorderProfile.QUALITY_TIME_LAPSE_QCIF:
return CamcorderProfile.QUALITY_TIME_LAPSE_QCIF;
case CamcorderProfile.QUALITY_TIME_LAPSE_QVGA:
return CamcorderProfile.QUALITY_TIME_LAPSE_QVGA;
case CamcorderProfile.QUALITY_TIME_LAPSE_CIF:
return CamcorderProfile.QUALITY_TIME_LAPSE_CIF;
case CamcorderProfile.QUALITY_TIME_LAPSE_LOW:
return CamcorderProfile.QUALITY_TIME_LAPSE_LOW;
case CamcorderProfile.QUALITY_HIGH_SPEED_480P:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return CamcorderProfile.QUALITY_HIGH_SPEED_480P;
}
case CamcorderProfile.QUALITY_HIGH_SPEED_LOW:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return CamcorderProfile.QUALITY_HIGH_SPEED_LOW;
}
}
return CamcorderProfile.QUALITY_HIGH;
}
private void setupAutoStopRecordingFactors() {
if (settingsModel.isRecordingScheduled() && isValidTime(settingsModel.getWakeUpTimeForTimer())) {
mediaRecorder.setMaxDuration(settingsModel.getScheduleRecordingTimeDuration() * 60 * 1000);
if (settingsModel.isMaxFileSize())
mediaRecorder.setMaxFileSize(settingsModel.getMaxFileSizeLimit() * 1024 * 1024);
} else {
if (settingsModel.isLimitRecordingTime())
mediaRecorder.setMaxDuration(settingsModel.getRecordingTimeLimit() * 60 * 1000);
if (settingsModel.isMaxFileSize())
mediaRecorder.setMaxFileSize(settingsModel.getMaxFileSizeLimit() * 1024 * 1024);
}
mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
@Override
public void onInfo(MediaRecorder mediaRecorder, int i, int i1) {
if (i == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
stopSelf();
} else if (i == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
stopSelf();
}
}
});
}
public boolean isValidTime(long wakeUpTimeInMillis) {
Calendar smsTime = Calendar.getInstance();
smsTime.setTimeInMillis(wakeUpTimeInMillis);
Calendar now = Calendar.getInstance();
if (now.get(Calendar.DATE) == smsTime.get(Calendar.DATE)) {
if (now.get(Calendar.HOUR_OF_DAY) == smsTime.get(Calendar.HOUR_OF_DAY)) {
if (now.get(Calendar.MINUTE) == smsTime.get(Calendar.MINUTE))
return true;
}
}
return false;
}
private void setupCameraOrientation() {
if (settingsModel.getCameraSide().equals("front")) {
if (settingsModel.getCameraOrientation().equals("auto") || settingsModel.getCameraOrientation().equals("portrait")) {
mediaRecorder.setOrientationHint(270);
} else
mediaRecorder.setOrientationHint(0);
} else {
if (settingsModel.getCameraOrientation().equals("auto") || settingsModel.getCameraOrientation().equals("portrait")) {
mediaRecorder.setOrientationHint(90);
} else
mediaRecorder.setOrientationHint(180);
}
}
private void setupCameraParametersForRecording() {
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> ss = parameters.getSupportedVideoSizes();
Log.d("------ 0", ss.get(0).width + " " + ss.get(0).height);
Log.d("------ last", ss.get(ss.size() - 1).width + " " + ss.get(ss.size() - 1).height);
List<Camera.Size> sizes = parameters.getSupportedVideoSizes();
for (Camera.Size s : sizes)
Log.d("----", String.valueOf(s.width) + " * " + String.valueOf(s.height));
if (settingsModel.isFlashlightWhileRec() && !settingsModel.getCameraSide().equalsIgnoreCase("front"))
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
//_______ setup zoom factor ___________
if (settingsModel.isZoomEnabled()) {
if (parameters.isZoomSupported()) {
if (settingsModel.getZoomInValue() >= 0 && settingsModel.getZoomInValue() <= parameters.getMaxZoom()) {
parameters.setZoom(settingsModel.getZoomInValue());
}
}
}
camera.setParameters(parameters);
}
private void setupCameraSide() {
if (settingsModel.getCameraSide().equals("front"))
camera = openFrontFacingCamera();
else
camera = Camera.open();
}
private void startRecording() {
try {
mediaRecorder.prepare();
mediaRecorder.start();
saveRecStartingTime();
if (SharedPreferenceUtility.getPreference(this, PreferenceKeys.IS_APP_RUNNING, false))
updateViewsOnStartRec();
} catch (Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void updateViewsOnStartRec() {
sflStartStopRecProgress.stopShimmerAnimation();
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.setText("00:00:00");
chronometer.start();
fabStartStopRec.setIcon(getResources().getDrawable(R.drawable.stop_icon), getResources().getDrawable(R.drawable.start_icon));
fabStartStopRec.showProgress(true);
fabStartStopRec.setIndeterminate(true);
runnable = new Runnable() {
@Override
public void run() {
fabStartStopRec.setEnabled(true);
}
};
enableViewsHandler = new Handler();
enableViewsHandler.postDelayed(runnable, 1000);
}
private void saveRecStartingTime() {
SharedPreferenceUtility.setPreference(this, PreferenceKeys.IS_RECORDING, true);
SharedPreferenceUtility.setPreference(this, PreferenceKeys.REC_STARTING_TIME, System.currentTimeMillis());
}
private void setupVideoStorage() {
//___________ creating new directory __________
File f = new File(settingsModel.getStoragePath(), settingsModel.getStorageFolderName());
if (!f.exists()) {
f.mkdirs();
}
if (isExternalStorageWritable()) {
try {
fileName = settingsModel.getStoragePath() + "/" + settingsModel.getStorageFolderName() + "/" +
DateFormat.format(settingsModel.getFileNameFormat(), new Date().getTime()) + ".mp4";
mediaRecorder.setOutputFile(fileName);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, R.string.you_dont_have_enough_space_, Toast.LENGTH_SHORT).show();
}
}
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
// Stop recording and remove SurfaceView
@Override
public void onDestroy() {
updateViewsOnStopRec();
updateSqlite();
//_________ if camera was not available __________
if (camera != null && mediaRecorder != null) {
final File file = new File(fileName);
saveAndScanFile(file.getAbsolutePath());
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
camera.lock();
camera.release();
Camera.CameraInfo info = new Camera.CameraInfo();
if (info.canDisableShutterSound) {
camera.enableShutterSound(true);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// to mute shutter sound of camera
final AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, false);
mgr.setStreamSolo(AudioManager.STREAM_SYSTEM, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (mgr.isStreamMute(AudioManager.STREAM_MUSIC))
mgr.setStreamMute(AudioManager.STREAM_MUSIC, false);
}
} else {
}
/*if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
// to unmute shutter sound of camera
AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, false);
} else {
Camera.CameraInfo info = new Camera.CameraInfo();
if (info.canDisableShutterSound) {
camera.enableShutterSound(true);
}
}*/
windowManager.removeView(surfaceView);
if (settingsModel.isShowNotificationOnRecStarts())
unregisterReceiver(stopServiceBroadcast);
if (settingsModel.isShowNotificationOnRecStops()) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
sendRecordedVideoNotification(file.getAbsolutePath());
}
}, 1000);
}
setupRiningAndVIberationOnStopRec();
if (SharedPreferenceUtility.getPreference(this, PreferenceKeys.IS_APP_RUNNING, false) && runnable != null)
enableViewsHandler.removeCallbacks(runnable);
}
}
private void setupRiningAndVIberationOnStopRec() {
if (settingsModel.isRingsOnRecStops()) {
Uri ringTuneUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.rec_end_sound);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), ringTuneUri);
r.play();
}
if (settingsModel.isVibrateOnRecStops()) {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else
v.vibrate(500);
}
}
private void updateViewsOnStopRec() {
if (SharedPreferenceUtility.getPreference(this, PreferenceKeys.IS_APP_RUNNING, false)) {
if (chronometer != null)
chronometer.stop();
fabStartStopRec.setIcon(getResources().getDrawable(R.drawable.start_icon), getResources().getDrawable(R.drawable.stop_icon));
fabStartStopRec.showProgress(false);
fabStartStopRec.setIndeterminate(false);
if (sflStartStopRecProgress.isAnimationStarted())
sflStartStopRecProgress.stopShimmerAnimation();
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void showCustomNotification(String fileName, String videoPath) {
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.single_expanded_notification_layout);
contentView.setTextViewText(R.id.tv_app_name, "Private Video Recorder");
contentView.setTextViewText(R.id.tv_video_name, fileName);
contentView.setImageViewBitmap(R.id.iv_video_image, getVideoThumbnail(videoPath));
Intent playVideoIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(videoPath));
playVideoIntent.setDataAndType(Uri.parse(videoPath), "video/mp4");
PendingIntent playVideoPendingIntent = PendingIntent.getActivity(this, 0, playVideoIntent, 0);
contentView.setOnClickPendingIntent(R.id.btn_play_video, playVideoPendingIntent);
contentView.setOnClickPendingIntent(R.id.btn_cancel, PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), 0, null));
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setCustomBigContentView(contentView);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(1, notification);
}
private void notificationToShowRecordingStarted() {
registerBroadcastToStopRec();
Intent notificationIntent = new Intent("stop_recording_action");
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, notificationIntent, 0);
Notification notification = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
/*if (settingsModel.isShowNotificationOnRecStarts() || settingsModel.isRecordingScheduled() || !SharedPreferenceUtility.getPreference(this, PreferenceKeys.IS_APP_RUNNING, false)) {*/
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, createNotificationChannel());
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.recording_running_icon)
.setContentTitle(getString(R.string.private_video_recorder))
.setContentText(getString(R.string.click_to_stop_recording))
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentIntent(pendingIntent)
.build();
int REC_STARTS_NOTIFICATION_ID = 123;
startForeground(REC_STARTS_NOTIFICATION_ID, notification);
/*}*/
} else {
if (settingsModel.isShowNotificationOnRecStarts()) {
notification = new Notification.Builder(this)
.setSound(null)
.setVibrate(null)
.setContentTitle(getString(R.string.private_video_recorder))
.setContentText(getString(R.string.click_to_stop_recording))
.setSmallIcon(R.mipmap.recording_running_icon)
.setContentIntent(pendingIntent)
.build();
int REC_STARTS_NOTIFICATION_ID = 123;
startForeground(REC_STARTS_NOTIFICATION_ID, notification);
}
}
// notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// notification.flags |= Notification.FLAG_AUTO_CANCEL;
/*int REC_STARTS_NOTIFICATION_ID = 123;
startForeground(REC_STARTS_NOTIFICATION_ID, notification);*/
}
private Camera openFrontFacingCamera() {
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
camera = Camera.open(camIdx);
} catch (RuntimeException e) {
Toast.makeText(this, getString(R.string.camera_failed_to_open_) + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}
return camera;
}
private void updateSqlite() {
SettingsModel settingsModel = SettingsModel.findById(SettingsModel.class, 1L);
settingsModel.setRecordingScheduled(false);
settingsModel.save();
SharedPreferenceUtility.setPreference(this, PreferenceKeys.IS_RECORDING, false);
}
}
公共类RecorderService扩展服务实现SurfaceHolder.Callback{
专用WindowManager WindowManager;
私人SurfaceView SurfaceView;
私人摄像机=空;
专用MediaRecorder MediaRecorder=null;
私有字符串fileName=“”;
私人停止服务广播停止服务广播;
私有字符串endRecordingDate;
私有字符串endRecordingTime;
私人设置模型设置模型;
私有处理程序启用ViewShandler;
私人可运行;
@RequiresApi(api=Build.VERSION\u CODES.JELLY\u BEAN)
@凌驾
public void onCreate(){
settingsModel=settingsModel.findById(settingsModel.class,1L);
setupSurfaceViewForRecording();
}
私有void setupSurfaceViewForRecording(){
int布局_标志;
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.O){
LAYOUT_FLAG=WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}否则{
LAYOUT_FLAG=WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
}
//创建新的SurfaceView,将其大小设置为1x1,将其移动到左上角,并将此服务设置为回调
windowManager=(windowManager)this.getSystemService(Context.WINDOW\u服务);
surfaceView=新的surfaceView(本);
WindowManager.LayoutParams LayoutParams=新建WindowManager.LayoutParams(
1, 1,
//WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
//WindowManager.LayoutParams.FLAG\u WATCH\u Out\u TOUCH,
布图(u)旗,,
WindowManager.LayoutParams.FLAG_不可触摸| WindowManager.LayoutParams.FLAG_屏幕中的布局| WindowManager.LayoutParams.FLAG_不可聚焦,
像素格式。半透明
);
layoutParams.gravity=gravity.LEFT | gravity.TOP;
windowManager.addView(surfaceView、layoutParams);
surfaceView.getHolder().addCallback(此);
}
私有无效注册表broadcasttostoprec(){
stopServiceBroadcast=新的stopServiceBroadcast();
IntentFilter filter=新的IntentFilter(“停止录制动作”);
registerReceiver(stopServiceBroadcast,过滤器);
}
//创建曲面后立即调用的方法(初始化并启动MediaRecorder)
@凌驾
已创建的公共空隙表面(表面层表面层){
mediaRecorder=新的mediaRecorder();
setupCameraSide();
//if(设置model.getCameraSide().equalsIgnoreCase(“前端”)和&!getPackageManager().hasSystemFeature(PackageManager.FEATURE\u CAMERA\u前端)){
//Toast.makeText(这个,R.string.front\u摄像头\u不可用\u,Toast.LENGTH\u SHORT.show();
//if(SharedPreferenceUtility.getInstance().getBooleanPreference(PreferenceKeys.IS_APP_RUNNING))
//fabStartStopRec.setEnabled(真);
//这个。stopSelf();
//返回;
//