Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ ext {
}

buildscript {
ext {
agp_version = '8.2.2'
}
repositories {
mavenCentral()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.7.2'
classpath "com.android.tools.build:gradle:$agp_version"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
Expand All @@ -45,6 +46,8 @@
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import android.widget.ImageView;
import android.widget.Toast;

public class CameraActivity extends Fragment {

Expand Down Expand Up @@ -105,7 +108,7 @@ private enum RecordingState {
public int height;
public int x;
public int y;

private ImageView focusRingView;
public void setEventListener(CameraPreviewListener listener) {
eventListener = listener;
}
Expand Down Expand Up @@ -307,7 +310,6 @@ private void handleZoom(MotionEvent event, Camera.Parameters params) {
}
);
}

private void setDefaultCameraId() {
// Find the total number of cameras available
numberOfCameras = Camera.getNumberOfCameras();
Expand Down Expand Up @@ -982,7 +984,7 @@ public void muteStream(boolean mute, Activity activity) {
int direction = mute ? audioManager.ADJUST_MUTE : audioManager.ADJUST_UNMUTE;
}

public void setFocusArea(final int pointX, final int pointY, final Camera.AutoFocusCallback callback) {
/*public void setFocusArea(final int pointX, final int pointY, final Camera.AutoFocusCallback callback) {
if (mCamera != null) {
mCamera.cancelAutoFocus();

Expand All @@ -1005,8 +1007,116 @@ public void setFocusArea(final int pointX, final int pointY, final Camera.AutoFo
callback.onAutoFocus(false, this.mCamera);
}
}
}*/
public void setFocusArea(final int pointX, final int pointY, final Camera.AutoFocusCallback callback) {

if (mCamera != null) {
CharSequence text ;
int duration;

Toast toast ;
mCamera.cancelAutoFocus();

Camera.Parameters parameters = mCamera.getParameters();
if (parameters.getMaxNumFocusAreas() > 0) {
Rect focusRect = calculateTapArea(pointX, pointY,1.5f);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
parameters.setFocusAreas(Arrays.asList(new Camera.Area(focusRect, 1000)));

if (parameters.getMaxNumMeteringAreas() > 0) {
parameters.setMeteringAreas(Arrays.asList(new Camera.Area(focusRect, 1000)));
}

try {
setCameraParameters(parameters);

// Show visual indicator (UI Overlay)
showFocusIndicator(pointX, pointY);

// Trigger autofocus
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
Log.d(TAG, "Tap-to-Focus successful");

// Auto-reset focus mode to CONTINUOUS_PICTURE after 3 seconds
new Handler().postDelayed(() -> {
Camera.Parameters resetParams = mCamera.getParameters();
resetParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
setCameraParameters(resetParams);
}, 500);
} else {
Log.d(TAG, "Tap-to-Focus failed");
}
callback.onAutoFocus(success, camera);
}
});

} catch (Exception e) {
Log.e(TAG, "Tap-to-focus failed: " + e.getMessage(), e);
callback.onAutoFocus(false, this.mCamera);
}
} else {
/*text = "Device does not support focus areas!";
duration = Toast.LENGTH_SHORT;

toast = Toast.makeText(getActivity(), text, duration);
toast.show();
Log.d(TAG, "Device does not support focus areas");*/
}
}else{
/*CharSequence text = "Camera not available!";
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(getActivity(), text, duration);
toast.show();*/
}
}
private void showFocusIndicator(final int x, final int y) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// Remove previous focus ring (if any)
if (focusRingView != null) {
frameContainerLayout.removeView(focusRingView);
}

// Create a new ImageView for the focus ring
focusRingView = new ImageView(getActivity());

// Get focus ring drawable dynamically

int focusRingId = getResources().getIdentifier("focus_ring", "drawable", appResourcesPackage);


//Toast.makeText(getActivity(),focusRingId,Toast.LENGTH_SHORT).show();
focusRingView.setImageResource(focusRingId);

// Set size of focus ring (adjust if needed)
int focusSize = 200;
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(focusSize, focusSize);
params.leftMargin = x - (focusSize / 2);
params.topMargin = y - (focusSize / 2);
focusRingView.setLayoutParams(params);

// Add focus ring to the camera preview layout
frameContainerLayout.addView(focusRingView);

// Animate: Fade out and remove after 1 second
focusRingView.animate()
.alpha(0f)
.setDuration(800)
.withEndAction(new Runnable() {
@Override
public void run() {
frameContainerLayout.removeView(focusRingView);
}
})
.start();
}
});
}
private Rect calculateTapArea(float x, float y, float coefficient) {
if (x < 100) {
x = 100;
Expand Down
18 changes: 18 additions & 0 deletions android/src/main/res/drawable/focus_ring.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Outer glowing ring -->
<item>
<shape android:shape="oval">
<solid android:color="@android:color/transparent"/>
<stroke android:width="10dp" android:color="#80FFFFFF"/> <!-- Semi-transparent white -->
</shape>
</item>

<!-- Inner main focus ring -->
<item>
<shape android:shape="oval">
<solid android:color="@android:color/transparent"/>
<stroke android:width="4dp" android:color="@android:color/white"/>
</shape>
</item>
</layer-list>
2 changes: 2 additions & 0 deletions src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export interface CameraPreviewOptions {
enableOpacity?: boolean;
/** Defaults to false - Android only. Set if camera preview will support pinch to zoom. */
enableZoom?: boolean;
/** Defaults to false - Android only. Set if camera preview will support tap to focus. */
tapToFocus?: boolean;
}
export interface CameraPreviewPictureOptions {
/** The picture height, optional, default 0 (Device default) */
Expand Down