๊ฒฝ์ฐ android.hardware.Camera์ฌ์ฉ๋์ง ์์ผ๋ฉฐ ๋น์ ์ด ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค Camera๋ค์, ์ด๋ค์ด์ ๋ํ ๋์์ ๊ฒ์
๋๊น?
๋ต๋ณ
API ๋ฌธ์
์ ๋ํ Android ๊ฐ๋ฐ์ ๊ฐ์ด๋ ์ ๋ฐ๋ฅด๋ฉด android.hardware.Camera๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์๋ก์ด ์ ํ๋ฆฌ์ผ์ด์ ์๋ ์๋ก์ด android.hardware.camera2 API๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค .
์ ๋ํ ์ ๋ณด ํ์ด์ง android.hardware.camera2(์์ ๋งํฌ ๋จ)์ ๋ค์๊ณผ ๊ฐ์ด ๋ช
์๋์ด ์์ต๋๋ค.
android.hardware.camera2 ํจํค์ง๋ Android ๊ธฐ๊ธฐ์ ์ฐ๊ฒฐ๋ ๊ฐ๋ณ ์นด๋ฉ๋ผ ๊ธฐ๊ธฐ์ ๋ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ Camera ํด๋์ค๋ฅผ ๋์ฒดํฉ๋๋ค.
๋ฌธ์
ํด๋น ๋ฌธ์๋ฅผ ํ์ธํ๋ฉด์ด ๋ ๊ฐ์ง Camera API์ ๊ตฌํ์ด ๋งค์ฐ ๋ค๋ฅด๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ์นด๋ฉ๋ผ ๋ฐฉํฅ ์ค์ android.hardware.camera
@Override
public int getOrientation(final int cameraId) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
return info.orientation;
}
๋ android.hardware.camera2
@Override
public int getOrientation(final int cameraId) {
try {
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] cameraIds = manager.getCameraIdList();
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
} catch (CameraAccessException e) {
// TODO handle error properly or pass it on
return 0;
}
}
์ด๋ก ์ธํด ํ๋์์ ๋ค๋ฅธ ๊ฒ์ผ๋ก ์ ํํ๊ณ ๋ ๊ตฌํ์ ๋ชจ๋ ์ฒ๋ฆฌ ํ ์์๋ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค.
์ด ๋จ์ผ ์ฝ๋ ์์ ์์๋ ์ด์ ์นด๋ฉ๋ผ API๊ฐ int์นด๋ฉ๋ผ ID์ ๊ธฐ๋ณธ ์์ ์ ํจ๊ป ์๋ํ๋ ๋ฐ๋ฉด ์ ์นด๋ฉ๋ผ API๋ String๊ฐ์ฒด ์ ํจ๊ป ์๋ ํ๋ค๋ ์ฌ์ค์ ์ด๋ฏธ ํด๊ฒฐํด์ผํ์ต๋๋ค . ์ด ์์์๋ int๋ฅผ ์ API์ ์ธ๋ฑ์ค๋ก ์ฌ์ฉํ์ฌ ์ ์ํ๊ฒ ์์ ํ์ต๋๋ค. ์นด๋ฉ๋ผ ๋ฐํ์ด ํญ์ ๋์ผํ ์์๊ฐ ์๋ ๊ฒฝ์ฐ ์ด๋ฏธ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋์ฒด ์ ๊ทผ ๋ฐฉ์์ ์๋ง๋ ๋ ์์ ํ ์ด์ int cameraID์ String ๊ฐ์ฒด ๋ฐ String ํํ์ผ๋ก ์์
ํ๋ ๊ฒ์
๋๋ค.
์ฃผ์์ ํ๋ ๋จ์ด์ ธ
์ด์ ์ด ํฐ ์ฐจ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋จผ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ์ฝ๋์์ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ์ฐธ์กฐ ํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ํด๋น ์ธํฐํ์ด์ค์ ๋ ๊ฐ์ง ๊ตฌํ์ ๋ํ ๋ช ๊ฐ์ง ์ฝ๋๋ฅผ ๋์ดํฉ๋๋ค. ์์ ๋์ ์ ํํ๊ธฐ ์ํด ์นด๋ฉ๋ผ API๋ฅผ ์ค์ ๋ก ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ๊ตฌํ์ ์ ํ ํ ์ ์์ต๋๋ค.
๋ค์ ์น์ ์์๋ ๋ ์ค ํ๋๋ฅผ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ๋น ๋ฅด๊ฒ ์ค๋ช ํ๊ฒ ์ต๋๋ค.
์ด ์์ ๋ฅผ ์ ํํ๊ธฐ ์ํด ํ์ํ ๋ชจ๋ ๊ฒ์ ๋ํํ๋ ์ธํฐํ์ด์ค๋ ์ฌ๊ธฐ์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ ๋ง ์์ต๋๋ค.
public interface CameraSupport {
CameraSupport open(int cameraId);
int getOrientation(int cameraId);
}
์ด์ ์ด์ ์นด๋ฉ๋ผ ํ๋์จ์ด API์ ๋ํ ํด๋์ค๊ฐ ์์ต๋๋ค.
@SuppressWarnings("deprecation")
public class CameraOld implements CameraSupport {
private Camera camera;
@Override
public CameraSupport open(final int cameraId) {
this.camera = Camera.open(cameraId);
return this;
}
@Override
public int getOrientation(final int cameraId) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
return info.orientation;
}
}
๊ทธ๋ฆฌ๊ณ ์๋ก์ด ํ๋์จ์ด API์ ๋ํ ๋ ๋ค๋ฅธ ํ๋ :
public class CameraNew implements CameraSupport {
private CameraDevice camera;
private CameraManager manager;
public CameraNew(final Context context) {
this.manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
}
@Override
public CameraSupport open(final int cameraId) {
try {
String[] cameraIds = manager.getCameraIdList();
manager.openCamera(cameraIds[cameraId], new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
CameraNew.this.camera = camera;
}
@Override
public void onDisconnected(CameraDevice camera) {
CameraNew.this.camera = camera;
// TODO handle
}
@Override
public void onError(CameraDevice camera, int error) {
CameraNew.this.camera = camera;
// TODO handle
}
}, null);
} catch (Exception e) {
// TODO handle
}
return this;
}
@Override
public int getOrientation(final int cameraId) {
try {
String[] cameraIds = manager.getCameraIdList();
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
} catch (CameraAccessException e) {
// TODO handle
return 0;
}
}
}
์ ์ ํ API๋ก๋
์ด์ ๊ทํ CameraOld๋๋ CameraNewํด๋์ค ๋ฅผ๋ก๋ ํ๋ ค๋ฉด CameraNewAPI ๋ ๋ฒจ 21์์๋ง ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก API ๋ ๋ฒจ์ ํ์ธํด์ผํฉ๋๋ค .
์ด๋ฏธ ์ข
์์ฑ ์ฃผ์
์ ์ค์ ํ ๊ฒฝ์ฐ CameraSupport๊ตฌํ์ ์ ๊ณต ํ ๋ ๋ชจ๋์์์ด๋ฅผ ์ํ ํ ์ ์์ต๋๋ค . ์:
@Module public class CameraModule {
@Provides
CameraSupport provideCameraSupport(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return new CameraNew(context);
} else {
return new CameraOld();
}
}
}
DI๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ ์ ํธ๋ฆฌํฐ๋ฅผ ๋ง๋ค๊ฑฐ๋ Factory ํจํด์ ์ฌ์ฉํ์ฌ ์ ์ ํ ๊ฒ์ ๋ง๋ค ์ ์์ต๋๋ค. ์ค์ํ ๋ถ๋ถ์ API ๋ ๋ฒจ์ด ํ์ธ๋๋ค๋ ๊ฒ์ ๋๋ค.
๋ต๋ณ
๋์ผํ ๋ฌธ์ ์ ์ง๋ฉด ํ์ฌ ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ ์นด๋ฉ๋ผ API๋ฅผ ํตํด ์ด์ ๊ธฐ๊ธฐ๋ฅผ ์ง์ํ๊ณ ํ์ฌ ๊ธฐ๊ธฐ ๋ชจ๋์ ์๋ก์ด Camera2 API๊ฐ ํ์ํ๋ฉฐ ๋ฏธ๋๋ก ์ด๋ํฉ๋๋ค. ๋๋ ๋์ผํ ๋ฌธ์ ์ ๋ถ๋ช ํ๊ณ ๋ API๋ฅผ ์ฐ๊ฒฐํ๋ ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐพ์ง ๋ชปํ์ต๋๋ค. ๋งค์ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ OOP ์ฃผ์ฒด๋ก ์ ํํ์ต๋๋ค .
2 ๊ฐ์ API๋ ํ์ ํ๊ฒ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์ด์ API์ ์ ๊ณต๋ ์ธํฐํ์ด์ค๋ฅผ ์์ํ๋ ํด๋ผ์ด์ธํธ ๊ฐ์ฒด์์ ์ด๋ค์ ๊ตํํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ API์๋ ๋ค๋ฅธ ์ํคํ ์ฒ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ ๋ ๋ฉ์๋๊ฐ ๋ค๋ฅธ ์ฌ๋ฌ ๊ฐ์ฒด๊ฐ ์์ต๋๋ค. Google์ ๋ํ ์ฌ๋์ด ์์ง๋ง ragnabbit! ์ค๋ง ์ค๋ฝ๋ค์.
๊ทธ๋์ ์ฑ์ ํ์ํ ์นด๋ฉ๋ผ ๊ธฐ๋ฅ์๋ง ์ด์ ์ ๋ง์ถ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค๊ณ ํด๋น ์ธํฐํ์ด์ค ๋ฅผ ๊ตฌํํ๋ ๋ API์ ๋ํ ๊ฐ๋จํ ๋ํผ๋ฅผ ๋ง๋ค์์ต๋๋ค . ์ด๋ ๊ฒํ๋ฉด ์นด๋ฉ๋ผ ํ๋์ด ์ด๋ค ํ๋ซํผ์์ ์คํ๋๋์ง ์ ๊ฒฝ ์ธ ํ์๊ฐ ์์ต๋๋ค.
๋ํ API๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด Singleton์ ์ค์ ํ์ต๋๋ค. ์ด์ Android OS ๊ธฐ๊ธฐ์ ๊ฒฝ์ฐ ๋ด ์ธํฐํ์ด์ค๋ก ์ด์ API์ ๋ํผ๋ฅผ ์ธ์คํด์คํํ๊ณ ์ API๋ฅผ ์ฌ์ฉํ๋ ์ต์ ๊ธฐ๊ธฐ์ ๊ฒฝ์ฐ ์ API์ ๋ํผ ํด๋์ค๋ฅผ ์ธ์คํด์คํํฉ๋๋ค. ์ฑ๊ธ ํค์๋ API ๋ ๋ฒจ์ ๊ฐ์ ธ์จ ๋ค์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํ๋ ์ผ๋ฐ์ ์ธ ์ฝ๋๊ฐ ์์ต๋๋ค.
๋ ๋ํผ ํด๋์ค ์์ ๋์ผํ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉ ํ๋ฏ๋ก ์ฑ์ด Jellybean ๋๋ Marshmallow์์ ์คํ๋๋์ง ์ฌ๋ถ๋ ์ค์ํ์ง ์์ต๋๋ค. ์ธํฐํ์ด์ค๊ฐ ๋์ผํ ๋ฉ์๋ ์๋ช ์ ์ฌ์ฉํ์ฌ Camera API์์ ํ์ํ ๊ฒ์ ์ฑ์ ์ ๊ณตํ๋ ํ; ์นด๋ฉ๋ผ๋ Android์ ์ต์ ๋ฒ์ ๊ณผ ์ด์ ๋ฒ์ ๋ชจ๋์์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ฑ์์ ์คํ๋ฉ๋๋ค.
Singleton์ ๋ํ API์ ์ฐ๊ฒฐ๋์ง ์์ ๋ช ๊ฐ์ง ๊ด๋ จ ์์ ์ ์ํ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ฅ์น์ ์ค์ ๋ก ์นด๋ฉ๋ผ๊ฐ ์๋์ง ๊ฐ์งํ๊ณ ๋ฏธ๋์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฅํ๋ ๊ฒ์ ๋๋ค.
์์ด๋์ด๊ฐ ๋์์ด ๋์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๋ต๋ณ
์ด์ android.hardware.camera2๋ฅผ ์ฌ์ฉํด์ผํฉ๋๋ค. android.hardware.Camera๋ ๋ ์ด์ ์ฌ์ฉ๋์ง ์์ผ๋ฉฐ API> 23 FlashLight์์๋ง ์๋ํฉ๋๋ค.
public class MainActivity extends AppCompatActivity {
Button button;
Boolean light=true;
CameraDevice cameraDevice;
private CameraManager cameraManager;
private CameraCharacteristics cameraCharacteristics;
String cameraId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.button);
cameraManager = (CameraManager)
getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = cameraManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(light){
try {
cameraManager.setTorchMode(cameraId,true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
light=false;}
else {
try {
cameraManager.setTorchMode(cameraId,false);
} catch (CameraAccessException e) {
e.printStackTrace();
}
light=true;
}
}
});
}
}
๋ต๋ณ
์ฌ์ฉํ ์นด๋ฉ๋ผ API์ ๋ํ ๋ต๋ณ์ด ์๋ชป๋์์ต๋๋ค. ๋๋ ๋ถ์กฑํ๋ค๊ณ ๋งํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ผ๋ถ ํด๋ํฐ (์ : Samsung Galaxy S6)์ API ๋ ๋ฒจ 21 ์ด์์ผ ์ ์์ง๋ง ์ฌ์ ํ Camera2 API๋ฅผ ์ง์ํ์ง ์์ ์ ์์ต๋๋ค.
CameraCharacteristics mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId);
Integer level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (level == null || level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
return false;
}
Camera2Api์ CameraManager ํด๋์ค์๋ ์นด๋ฉ๋ผ ํน์ฑ์ ์ฝ๋ ๋ฉ์๋๊ฐ ์์ต๋๋ค. ํ๋์จ์ด ํ๋ช ํ ์ฅ์น๊ฐ Camera2 Api๋ฅผ ์ง์ํ๋์ง ํ์ธํด์ผํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ฌ๊ฐํ ์์ฉ ํ๋ก๊ทธ๋จ์์ ์๋ํ๊ฒํ๋ ค๋ฉด ์ฒ๋ฆฌํด์ผ ํ ๋ ๋ง์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ ํ๋์ ์ต์ ์ด ์ผ๋ถ ์ฅ์น์์ ์๋ํ์ง ์๊ฑฐ๋ ์ ํ๊ธฐ์ ๋ฐฐํฐ๋ฆฌ ์์ค์ด ์นด๋ฉ๋ผ์ RuntimeException์ ์์ฑํ๊ฑฐ๋ ์ ํ๊ธฐ๊ฐ ์๋ชป๋ ๊ฐ์ ๋ฐํ ํ ์ ์์ต๋๋ค. ์นด๋ฉ๋ผ ID ๋ฑ
๋ฐ๋ผ์ ์ต์ ์ ์ ๊ทผ ๋ฐฉ์์ ์ด๋ค ์ด์ ๋ก Camera2๊ฐ ์์๋์ง ์๋ ๊ฒฝ์ฐ Camera1์ ์๋ ํ ์ ์์ผ๋ฉฐ ์ด๊ฒ์ด ์คํจํ๋ฉด Android๋ฅผ ํธ์ถํ์ฌ ๊ธฐ๋ณธ ์นด๋ฉ๋ผ๋ฅผ ์ด ์ ์์ผ๋ฏ๋ก ๋์ฒด ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
๋ต๋ณ
if ( getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
CameraManager cameraManager=(CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = cameraManager.getCameraIdList()[0];
cameraManager.setTorchMode(cameraId,true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}