diff --git a/README.rst b/README.rst index ae8598b26..d3c9e6b55 100644 --- a/README.rst +++ b/README.rst @@ -35,4 +35,5 @@ Battery X X X X X X Native file chooser X X X Orientation X X Audio recording X X +Flash X X X ================================== ============= ============= === ======= === ===== diff --git a/plyer/__init__.py b/plyer/__init__.py index c519342dd..98bfe2f5e 100644 --- a/plyer/__init__.py +++ b/plyer/__init__.py @@ -61,3 +61,6 @@ #: Vibrator proxy to :class:`plyer.facades.Vibrator` vibrator = Proxy('vibrator', facades.Vibrator) + +#: Flash proxy to :class:`plyer.facades.Flash` +flash = Proxy('flash', facades.Flash) diff --git a/plyer/facades/__init__.py b/plyer/facades/__init__.py index e5560c08f..229c4a8c7 100644 --- a/plyer/facades/__init__.py +++ b/plyer/facades/__init__.py @@ -8,7 +8,7 @@ __all__ = ('Accelerometer', 'Audio', 'Battery', 'Camera', 'Compass', 'Email', 'FileChooser', 'GPS', 'Gyroscope', 'IrBlaster', 'Orientation', - 'Notification', 'Sms', 'TTS', 'UniqueID', 'Vibrator') + 'Notification', 'Sms', 'TTS', 'UniqueID', 'Vibrator', 'Flash') from plyer.facades.accelerometer import Accelerometer from plyer.facades.audio import Audio @@ -26,3 +26,4 @@ from plyer.facades.tts import TTS from plyer.facades.uniqueid import UniqueID from plyer.facades.vibrator import Vibrator +from plyer.facades.flash import Flash diff --git a/plyer/facades/flash.py b/plyer/facades/flash.py new file mode 100644 index 000000000..2d14d7011 --- /dev/null +++ b/plyer/facades/flash.py @@ -0,0 +1,40 @@ +# coding=utf-8 + +class Flash(object): + """Flash facade. + + .. versionadded:: 1.2.5 + + This can be used to activate the flash of your camera on + Android and iOS + """ + + def on(self): + """Activate the flash + """ + self._on() + + def off(self): + """Deactiavte the flash + """ + self._off() + + def release(self): + """Release any access to the Flash / Camera. + Call this when you're done using the Flash. + This will release the Camera, and stop any process. + + Next call to `_on` will reactivate it. + """ + self._release() + + # private + + def _on(self): + raise NotImplementedError() + + def _off(self): + raise NotImplementedError() + + def _release(self): + pass diff --git a/plyer/platforms/android/flash.py b/plyer/platforms/android/flash.py new file mode 100644 index 000000000..10e2c1a42 --- /dev/null +++ b/plyer/platforms/android/flash.py @@ -0,0 +1,55 @@ +# coding=utf-8 +""" +Flash +----- +""" + +from plyer.facades import Flash +from jnius import autoclass +from plyer.platforms.android import activity + +Camera = autoclass("android.hardware.Camera") +CameraParameters = autoclass("android.hardware.Camera$Parameters") +SurfaceTexture = autoclass("android.graphics.SurfaceTexture") +PackageManager = autoclass('android.content.pm.PackageManager') +pm = activity.getPackageManager() +flash_available = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH) + + +class AndroidFlash(Flash): + _camera = None + + def _on(self): + if self._camera is None: + self._camera_open() + if not self._camera: + return + self._camera.setParameters(self._f_on) + + def _off(self): + if not self._camera: + return + self._camera.setParameters(self._f_off) + + def _release(self): + if not self._camera: + return + self._camera.stopPreview() + self._camera.release() + self._camera = None + + def _camera_open(self): + if not flash_available: + return + self._camera = Camera.open() + self._f_on = cam.getParameters() + self._f_off = cam.getParameters() + self._f_on.setFlashMode(CameraParameters.FLASH_MODE_TORCH) + self._f_off.setFlashMode(CameraParameters.FLASH_MODE_OFF) + self._camera.startPreview() + # Need this for Nexus 5 + self._camera.setPreviewTexture(SurfaceTexture(0)) + + +def instance(): + return AndroidFlash() diff --git a/plyer/platforms/ios/flash.py b/plyer/platforms/ios/flash.py new file mode 100644 index 000000000..a2c7afe91 --- /dev/null +++ b/plyer/platforms/ios/flash.py @@ -0,0 +1,50 @@ +# coding=utf-8 +""" +Flash +----- +""" + +from pyobjus import autoclass + +NSString = autoclass("NSString") +AVCaptureDevice = autoclass("AVCaptureDevice") +AVMediaTypeVideo = NSString.alloc().initWithUTF8String_("vide") +AVCaptureTorchModeOff = 0 +AVCaptureTorchModeOn = 1 + + +class IosFlash(Flash): + _camera = None + + def _on(self): + if self._camera is None: + self._camera_open() + if not self._camera: + return + self._camera.lockForConfiguration_(None) + try: + self._camera.setTorchMode(AVCaptureTorchModeOn) + finally: + self._camera.unlockForConfiguration() + + def _off(self): + if not self._camera: + return + self._camera.lockForConfiguration_(None) + try: + self._camera.setTorchMode(AVCaptureTorchModeOff) + finally: + self._camera.unlockForConfiguration() + + def _release(self): + pass + + def _camera_open(self): + device = AVCaptureDevice.defaultDeviceWithMediaType_(AVMediaTypeVideo) + if not device: + return + self._camera = device + + +def instance(): + return IosFlash()