バックグラウンドビデオ録画をAndroid 4.0で整理しようとしています。しかし、これらの問題のためにそれを行うことはできません:
MediaRecorderでダミーサーフェスが機能しない(エラー:無効なサーフェス)
アクティビティでSurface1 x 1 pxを使用する場合、Surfaceはアクティビティの一時停止時に破棄されます(記録は停止されます)
WindowsManagerでSurface1 x 1 pxを使用している場合、Surfaceはアプリケーションの一時停止時に破棄されます(記録は停止されます)
SurfaceTextureはMediaRecorder.setPreviewDisplay(new Surface(SurfaceTexture))では機能しません
ウィジェットはSurface1 x 1pxを処理できません
ステータスバーはSurface1 x 1pxを処理できません
どうか、正しい方法を見つけるのを手伝ってください。
サンプルと単純なコード(Jelly Bean、SGS2でテスト済み):
public class BackgroundVideoRecorder extends Service implements SurfaceHolder.Callback {
private WindowManager windowManager;
private SurfaceView surfaceView;
private Camera camera = null;
private MediaRecorder mediaRecorder = null;
@Override
public void onCreate() {
// Start foreground service to avoid unexpected kill
Notification notification = new Notification.Builder(this)
.setContentTitle("Background Video Recorder")
.setContentText("")
.setSmallIcon(R.drawable.ic_launcher)
.build();
startForeground(1234, notification);
// 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);
LayoutParams layoutParams = new WindowManager.LayoutParams(
1, 1,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT
);
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
windowManager.addView(surfaceView, layoutParams);
surfaceView.getHolder().addCallback(this);
}
// Method called right after Surface created (initializing and starting MediaRecorder)
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
camera = Camera.open();
mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mediaRecorder.setOutputFile(
Environment.getExternalStorageDirectory()+"/"+
DateFormat.format("yyyy-MM-dd_kk-mm-ss", new Date().getTime())+
".mp4"
);
try { mediaRecorder.prepare(); } catch (Exception e) {}
mediaRecorder.start();
}
// Stop recording and remove SurfaceView
@Override
public void onDestroy() {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
camera.lock();
camera.release();
windowManager.removeView(surfaceView);
}
@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; }
}
権限を忘れないでください:
<uses-permission Android:name="Android.permission.CAMERA" />
<uses-permission Android:name="Android.permission.RECORD_AUDIO" />
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
try {
mediaRecorder.prepare();
} catch (Exception e) {}
mediaRecorder.start();
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
stopSelf();
}
}, 5000);
}catch(Exception e){}
上記のコードを少し変更するだけで... 5秒のファイルがursdcardのルートフォルダに保存されます...必要に応じてタイマーを変更します。 Nexus4とMicromaxでも動作しました。