Merge pull request #1126 from mvpstars/feature/clear-window-background

Fix performance issue on Android: add option to clear window background when camera starts
This commit is contained in:
Sibelius Seraphini 2018-01-21 12:52:44 -02:00 committed by GitHub
commit 63d613af69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 10 deletions

View File

@ -347,6 +347,14 @@ from javascript.
If set to `true`, the device will not sleep while the camera preview is visible. This mimics the behavior of the default camera app, which keeps the device awake while open.
#### `Android` `clearWindowBackground`
Values:
`true`
`false` (default)
If you encounter performance issue while using a window background drawable (typically defined in theme to emulate splashscreen behavior), set this to true to automatically clear window background once camera is started.
#### `Android` `permissionDialogTitle`
Starting on android M individual permissions must be granted for certain services, the camera is one of them, you can use this to change the title of the dialog prompt requesting permissions.

View File

@ -24,6 +24,7 @@ public class RCTCameraView extends ViewGroup {
private String _captureQuality = "high";
private int _torchMode = -1;
private int _flashMode = -1;
private boolean _clearWindowBackground = false;
public RCTCameraView(Context context) {
super(context);
@ -77,6 +78,7 @@ public class RCTCameraView extends ViewGroup {
if (-1 != this._torchMode) {
_viewFinder.setTorchMode(this._torchMode);
}
_viewFinder.setClearWindowBackground(this._clearWindowBackground);
addView(_viewFinder);
}
}
@ -124,6 +126,13 @@ public class RCTCameraView extends ViewGroup {
RCTCamera.getInstance().setBarCodeTypes(types);
}
public void setClearWindowBackground(boolean clearWindowBackground) {
this._clearWindowBackground = clearWindowBackground;
if (this._viewFinder != null) {
this._viewFinder.setClearWindowBackground(clearWindowBackground);
}
}
private boolean setActualDeviceOrientation(Context context) {
int actualDeviceOrientation = getDeviceOrientation(context);
if (_actualDeviceOrientation != actualDeviceOrientation) {

View File

@ -4,7 +4,9 @@
package com.lwansbrough.RCTCamera;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
@ -41,6 +43,7 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText
private boolean _isStarting;
private boolean _isStopping;
private Camera _camera;
private boolean _clearWindowBackground = false;
private float mFingerSpacing;
// concurrency lock for barcode scanner to avoid flooding the runtime
@ -124,6 +127,11 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText
RCTCamera.getInstance().setFlashMode(_cameraType, flashMode);
}
public void setClearWindowBackground(boolean clearWindowBackground) {
this._clearWindowBackground = clearWindowBackground;
}
private void startPreview() {
if (_surfaceTexture != null) {
startCamera();
@ -180,6 +188,12 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText
_camera.setParameters(parameters);
_camera.setPreviewTexture(_surfaceTexture);
_camera.startPreview();
// clear window background if needed
if (_clearWindowBackground) {
Activity activity = getActivity();
if (activity != null)
activity.getWindow().setBackgroundDrawable(null);
}
// send previews to `onPreviewFrame`
_camera.setPreviewCallback(this);
} catch (NullPointerException e) {
@ -213,6 +227,17 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText
}
}
private Activity getActivity() {
Context context = getContext();
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity)context;
}
context = ((ContextWrapper)context).getBaseContext();
}
return null;
}
/**
* Parse barcodes as BarcodeFormat constants.
*
@ -500,4 +525,4 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
}
}

View File

@ -86,4 +86,9 @@ public class RCTCameraViewManager extends ViewGroupManager<RCTCameraView> {
}
view.setBarCodeTypes(result);
}
@ReactProp(name = "clearWindowBackground")
public void setClearWindowBackground(RCTCameraView view, boolean clearWindowBackground) {
view.setClearWindowBackground(clearWindowBackground);
}
}

View File

@ -87,6 +87,7 @@ export default class Camera extends Component {
onBarCodeRead: PropTypes.func,
barcodeScannerEnabled: PropTypes.bool,
cropToPreview: PropTypes.bool,
clearWindowBackground: PropTypes.bool,
onFocusChanged: PropTypes.func,
onZoomChanged: PropTypes.func,
mirrorImage: PropTypes.bool,
@ -117,6 +118,7 @@ export default class Camera extends Component {
torchMode: CameraManager.TorchMode.off,
mirrorImage: false,
cropToPreview: false,
clearWindowBackground: false,
barCodeTypes: Object.values(CameraManager.BarCodeType),
permissionDialogTitle: '',
permissionDialogMessage: '',
@ -191,18 +193,16 @@ export default class Camera extends Component {
message: this.props.permissionDialogMessage,
});
// On devices before SDK version 23, the permissions are automatically granted if they appear in the manifest,
// On devices before SDK version 23, the permissions are automatically granted if they appear in the manifest,
// so check and request should always be true.
// https://github.com/facebook/react-native-website/blob/master/docs/permissionsandroid.md
const isAuthorized = Platform.Version >= 23
? granted === PermissionsAndroid.RESULTS.GRANTED
: granted === true;
const isAuthorized =
Platform.Version >= 23 ? granted === PermissionsAndroid.RESULTS.GRANTED : granted === true;
this.setState({
isAuthorized,
isAuthorizationChecked: true
isAuthorized,
isAuthorizationChecked: true,
});
} else {
this.setState({ isAuthorized: true, isAuthorizationChecked: true });
}
@ -276,7 +276,7 @@ export default class Camera extends Component {
mirrorImage: props.mirrorImage,
fixOrientation: props.fixOrientation,
cropToPreview: props.cropToPreview,
...options
...options,
};
if (options.mode === Camera.constants.CaptureMode.video) {