이전에 알게된 액티비티 생명주기를 따라 코드를 읽어봅시다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 상태바를 안보이도록 합니다.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 화면 켜진 상태를 유지합니다.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
ImageButton button = findViewById(R.id.take_photo);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takePicture();
}
});
mSurfaceView = findViewById(R.id.surfaceView);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
deviceOrientation = new DeviceOrientation();
initSurfaceView();
}
위 코드는 액티비티가 생성될 때 실행되는 onCreate()메소드입니다.
getWindow()메소드는 화면의 꺼짐, 켜짐과 관련된 메소드로 액티비티 클래스에 종속되어 있다고 합니다. 주석과 같이 해당 기능을 적용해주기 위해 플래그를 set해줍니다.
setContentView()는 .java 와 .xml을 이어주는 메소드라고 생각하시면 됩니다. 파라미터에 xml 경로가 들어가는군요 #1에 있던 activity_main.xml입니다.
그 다음 줄은 버튼의 기능을 설정해주는데 xml의 id값으로 버튼을 특정할 수 있습니다. 그 id값과 .java의 변수를 연동시켜주는 것이 findViewById메소드입니다. take_photo 아이디를 가진 버튼의 기능이 설정하기 위해 OnClickListener를 달아줍니다. 그 안에 클릭되었을때의 기능을 설정하기 위해 onClick메소드가 있군요 따라서 위 코드는 take_photo 아이디를 가진 버튼이 클릭되었을 때 takePicture()메소드가 실행됩니다.
public void takePicture() {
try {
CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(mImageReader.getSurface());
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 화면 회전 안되게 고정시켜 놓은 상태에서는 아래 로직으로 방향을 얻을 수 없어서
// 센서를 사용하는 것으로 변경
//deviceRotation = getResources().getConfiguration().orientation;
mDeviceRotation = ORIENTATIONS.get(deviceOrientation.getOrientation());
Log.d("@@@", mDeviceRotation+"");
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mDeviceRotation);
CaptureRequest mCaptureRequest = captureRequestBuilder.build();
mSession.capture(mCaptureRequest, mSessionCaptureCallback, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
촬영관련은 디바이스와 호환이 요구되므로 트라이 캐치문으로 감싸주고 촬영 관련 클래스인 CaptureRequest.Builder를 생성해줍니다. 타겟을 설정해주고 모드를 설정해줍니다.
mDeviceRotation은 스마트폰을 회전시킬 때 스마트폰 내 센서(가속도계, 자이로센서)를 이용해 각도를 알아내 입력하는 변수입니다. 즉, deviceOrientation에 센서를 이용한 코드가 담겨있죠. 글이 너무 길어지므로 이 내용은 #3-1에서 다루겠습니다.
캡쳐리퀘스트 빌더에 jpeg 포맷 정보와 각도 정보를 설정해주고 빌드해줍니다. 그리고 현재 세션에 서페이스 스레드와 함께 캡쳐 리퀘스트를 설정해줍니다. 이때 콜백함수도 같이 넘겨주는데 콜백함수는 아래와 같이 촬영 성공, 실패, 촬영 중의 경우 기능으로 구성되어 있습니다.
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
mSession = session;
unlockFocus();
}
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
mSession = session;
}
@Override
public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
}
};
'안드로이드' 카테고리의 다른 글
"Trends and Predictions for Android App Development in 2021" (0) | 2023.05.03 |
---|---|
"Top 10 Android Apps for Boosting Productivity" (0) | 2023.05.03 |
[안드로이드] 밑바닥부터 딥러닝 호환 카메라 앱 만들기 #2 액티비티 생명주기 (0) | 2021.03.31 |
[안드로이드] 밑바닥부터 딥러닝 호환 카메라 앱 만들기 #1-2 Camera2 (0) | 2021.03.31 |
[안드로이드] 밑바닥부터 딥러닝 호환 카메라 앱 만들기 #1-1 SurfaceView (0) | 2021.03.31 |