Using Camera on android - android

In my library project I have the following code to initialize the camera, and start previewing.
public class CameraView {
private SurfaceView preview;
private SurfaceHolder previewHolder;
private Camera camera;
private boolean activeCamera;
private boolean cameraConfigured;
private Activity activity;
private final static int NINTY_DEGREES = 90;
public CameraView(Activity activity) {
this.activity = activity;
View rootView;
LayoutInflater inflater = activity.getLayoutInflater();
rootView = inflater.inflate(R.layout.layout_cameraview, null);
preview = (SurfaceView) rootView.findViewById(R.id.surfaceView);
previewHolder = preview.getHolder();
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraConfigured = false;
}
private void initializeCamera(int w, int h) {
if(camera != null && previewHolder.getSurface() != null) {
try
{
camera.setPreviewDisplay(previewHolder);
}
catch(Exception e)
{
Log.e("Camera: ", e.getMessage());
}
if(!cameraConfigured) {
Camera.Parameters params = camera.getParameters();
Camera.Size size = getBestPreviewSize(w, h, params);
if(size != null) {
params.setPreviewSize(size.width, size.height);
cameraConfigured = true;
}
}
}
}
public void startCamera() {
camera = Camera.open();
previewHolder.addCallback(surfaceCallback);
}
public void stopCamera() {
stopPreviewingOnDisplay();
}
public void takePicture() {
View rootView;
LayoutInflater inflater = activity.getLayoutInflater();
rootView = inflater.inflate(R.layout.layout_cameraview, null);
Button capture = (Button) rootView.findViewById(R.id.capture);
capture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("CameraView: ", "Capture button pressed!");
}
});
}
private void startPreviewingOnDisplay() {
if(camera != null) {
camera.setDisplayOrientation(NINTY_DEGREES);
camera.startPreview();
activeCamera = true;
}
}
private void stopPreviewingOnDisplay() {
if(camera != null && activeCamera) {
camera.stopPreview();
activeCamera = false;
}
}
private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
initializeCamera(width, height);
startPreviewingOnDisplay();
Log.d("CameraView: ", "SurfaceChanged");
}
};
private Camera.Size getBestPreviewSize(int w, int h, Camera.Parameters params) {
Camera.Size result = null;
for(Camera.Size size : params.getSupportedPreviewSizes()) {
if(size.width < w && size.height <= h) {
if(result == null) {
result = size;
}
else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if(newArea > resultArea)
result = size;
}
}
}
return(result);
}
}
The usage of this class:
public class History extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
camera = new CameraView(this);
}
#Override
public void onResume() {
super.onResume();
Log.i("History.class", "onResume called!");
camera.startCamera();
}
#Override
public void onPause() {
super.onPause();
camera.stopCamera();
}
}
I've debugged the code, and I notice that the camera object is being intitalized, but there is nothing appearing on the screen, it should have previewed the camera. Could anyone see whats wrong with this approach?
Thanks.

Related

Can't enable Flash with the Camera2 Api

I want to enable flash on/off in my camera app, but it isn't working,
Here's the code:
FlashActivity.java
public class FlashActivity extends AppCompatActivity {
private CameraManager mCameraManager;
private String mCameraId;
private Button mTorchOnOffButton;
private Boolean isTorchOn;
private TextureView textureView;
SeekBar sb;
TextToSpeech t1;
private String cameraId;
private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSessions;
private CaptureRequest.Builder captureRequestBuilder;
private Size imageDimension;
Bitmap src;
private static final int REQUEST_CAMERA_PERMISSION = 200;
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback()
{
#Override
public void onOpened(#NonNull CameraDevice camera) {
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
cameraDevice=null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("FlashActivity", "onCreate()");
setContentView(R.layout.activity_flash);
sb = (SeekBar) findViewById(R.id.seekBar2);
textureView = (TextureView) findViewById(R.id.textureView);
mTorchOnOffButton = (Button) findViewById(R.id.button_on_off);
isTorchOn = false;
textureView.setSurfaceTextureListener(textureListener);
t1 = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
t1.setLanguage(Locale.UK);
}
}
});
ToggleButton toggle = (ToggleButton) findViewById(R.id.toggleButton);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
freeze();
String toSpeak = "Camera Freeze";
Toast.makeText(getApplicationContext(), toSpeak, Toast.LENGTH_SHORT).show();
t1.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, null);
} else {
updatePreview();
String toSpeak = "Back to Live Camera";
Toast.makeText(getApplicationContext(), toSpeak, Toast.LENGTH_SHORT).show();
t1.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, null);
}
}
});
Boolean isFlashAvailable = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (!isFlashAvailable) {
AlertDialog alert = new AlertDialog.Builder(FlashActivity.this)
.create();
alert.setTitle("Error !!");
alert.setMessage("Your device doesn't support flash light!");
alert.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// closing the application
finish();
System.exit(0);
}
});
alert.show();
return;
}
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
mCameraId = mCameraManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}
mTorchOnOffButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
if (isTorchOn) {
turnOffFlashLight();
isTorchOn = false;
} else {
turnOnFlashLight();
isTorchOn = true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
float scale = ((progress / 10.0f) + 1);
textureView.setScaleX(scale);
textureView.setScaleY(scale);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void turnOnFlashLight() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mCameraManager.setTorchMode(mCameraId, true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void turnOffFlashLight() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mCameraManager.setTorchMode(mCameraId, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
ArrayList rev;
public void freeze() {
Thread td = new Thread(new Runnable() {
public void run() {
Bitmap bmp = textureView.getBitmap();
rev = new ArrayList<Bitmap>();
rev.add(bmp);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "" + rev.size(), Toast.LENGTH_LONG).show();
try {
cameraCaptureSessions.stopRepeating();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
});
}
});
td.start();
}
private void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
if (cameraDevice == null)
return;
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(FlashActivity.this, "Changed", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
if (cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
//Check realtime permission if run higher API 23
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId, stateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
openCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CAMERA_PERMISSION)
{
if(grantResults[0] != PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "You can't use camera without permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
protected void onStop() {
super.onStop();
if(isTorchOn){
turnOffFlashLight();
}
}
#Override
protected void onPause() {
super.onPause();
if(isTorchOn){
turnOffFlashLight();
}
}
#Override
protected void onResume() {
super.onResume();
if(isTorchOn){
turnOnFlashLight();
}
}
}
Here's what I get at LOG
04-03 16:38:34.948 10905-10905/com.example.sumesh.myapplication W/System.err: android.hardware.camera2.CameraAccessException: The camera device is in use already
at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:123)
at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73)
at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy0.setTorchMode(Unknown Source)
at android.hardware.camera2.CameraManager$CameraManagerGlobal.setTorchMode(CameraManager.java:884)
at android.hardware.camera2.CameraManager.setTorchMode(CameraManager.java:501)
at com.example.sumesh.myapplication.FlashActivity.turnOffFlashLight(FlashActivity.java:204)
at com.example.sumesh.myapplication.FlashActivity$5.onClick(FlashActivity.java:150)
at android.view.View.performClick(View.java:5215)
at android.view.View$PerformClick.run(View.java:21196)
}
I have used the linear layout instead of the relativeIlayout, but I
am unable to figure out what thing is exactly posing the error,
all the permissions are already defined in the android manifest,
any suggestions?
Try this , Full code for taking picture using camera2 API , Fragment_Camera4
/**
* A simple {#link Fragment} subclass.
*/
public class Fragment_Camera4 extends Fragment implements
AspectRatioFragment.Listener {
private View view;
private static final String TAG = "MainActivity";
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final String FRAGMENT_DIALOG = "dialog";
private static final int[] FLASH_OPTIONS = {
CameraView.FLASH_OFF,
CameraView.FLASH_ON,
};
private static final int[] FLASH_ICONS = {
R.drawable.ic_flash_off,
R.drawable.ic_flash_on,
};
private static final int[] FLASH_TITLES = {
R.string.flash_auto,
R.string.flash_off,
R.string.flash_on,
};
private int mCurrentFlash;
private CameraView mCameraView;
private Handler mBackgroundHandler;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_picture:
if (mCameraView != null) {
mCameraView.takePicture();
}
break;
case R.id.btn_switch_camera:
if (mCameraView != null) {
int facing = mCameraView.getFacing();
mCameraView.setFacing(facing == CameraView.FACING_FRONT ?
CameraView.FACING_BACK : CameraView.FACING_FRONT);
if (facing == CameraView.FACING_FRONT) {
btn_flash_onOff.setVisibility(View.VISIBLE);
} else {
btn_flash_onOff.setVisibility(View.GONE);
}
}
break;
case R.id.btn_flash_onOff:
if (mCameraView != null) {
mCurrentFlash = (mCurrentFlash + 1) % FLASH_OPTIONS.length;
btn_flash_onOff.setImageResource(FLASH_ICONS[mCurrentFlash]);
mCameraView.setFlash(FLASH_OPTIONS[mCurrentFlash]);
}
break;
}
}
};
ImageButton btn_flash_onOff;
public Fragment_Camera4() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_fragment__camera4, container, false);
mCameraView = (CameraView) view.findViewById(R.id.camera);
if (mCameraView != null) {
mCameraView.addCallback(mCallback);
}
ImageButton fab = (ImageButton) view.findViewById(R.id.take_picture);
ImageButton btn_switch_camera = (ImageButton) view.findViewById(R.id.btn_switch_camera);
btn_flash_onOff = (ImageButton) view.findViewById(R.id.btn_flash_onOff);
if (fab != null) {
fab.setOnClickListener(mOnClickListener);
btn_switch_camera.setOnClickListener(mOnClickListener);
btn_flash_onOff.setOnClickListener(mOnClickListener);
}
return view;
}
#Override
public void onResume() {
super.onResume();
mCameraView.start();
}
#Override
public void onPause() {
mCameraView.stop();
super.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
if (mBackgroundHandler != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBackgroundHandler.getLooper().quitSafely();
} else {
mBackgroundHandler.getLooper().quit();
}
mBackgroundHandler = null;
}
}
#Override
public void onAspectRatioSelected(#NonNull AspectRatio ratio) {
if (mCameraView != null) {
Toast.makeText(getActivity(), ratio.toString(), Toast.LENGTH_SHORT).show();
mCameraView.setAspectRatio(ratio);
}
}
private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread thread = new HandlerThread("background");
thread.start();
mBackgroundHandler = new Handler(thread.getLooper());
}
return mBackgroundHandler;
}
private CameraView.Callback mCallback
= new CameraView.Callback() {
#Override
public void onCameraOpened(CameraView cameraView) {
Log.d(TAG, "onCameraOpened");
}
#Override
public void onCameraClosed(CameraView cameraView) {
Log.d(TAG, "onCameraClosed");
}
#Override
public void onPictureTaken(CameraView cameraView, final byte[] data) {
Log.d(TAG, "onPictureTaken " + data.length);
Toast.makeText(cameraView.getContext(), R.string.picture_taken, Toast.LENGTH_SHORT)
.show();
getBackgroundHandler().post(new Runnable() {
#Override
public void run() {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/_saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
String final_path = myDir + "/" + fname;
OutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(data);
os.close();
} catch (IOException e) {
Log.w(TAG, "Cannot write to " + file, e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
}
}
Bundle bundle = new Bundle();
bundle.putString("path", final_path);
bundle.putString("type", "picture");
Fragment_Post_Image_Detail post_image_detail = new Fragment_Post_Image_Detail();
post_image_detail.setArguments(bundle);
((BaseActivity) getActivity()).replaceFragmentWithBackstack(post_image_detail);
}
});
}
};
}
Then Cameraview class
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.os.ParcelableCompat;
import android.support.v4.os.ParcelableCompatCreatorCallbacks;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Set;
public class CameraView extends FrameLayout {
/** The camera device faces the opposite direction as the device's screen. */
public static final int FACING_BACK = Constants.FACING_BACK;
/** The camera device faces the same direction as the device's screen. */
public static final int FACING_FRONT = Constants.FACING_FRONT;
/** Direction the camera faces relative to device screen. */
#IntDef({FACING_BACK, FACING_FRONT})
#Retention(RetentionPolicy.SOURCE)
public #interface Facing {
}
/** Flash will not be fired. */
public static final int FLASH_OFF = Constants.FLASH_OFF;
/** Flash will always be fired during snapshot. */
public static final int FLASH_ON = Constants.FLASH_ON;
/** Constant emission of light during preview, auto-focus and snapshot. */
public static final int FLASH_TORCH = Constants.FLASH_TORCH;
/** Flash will be fired automatically when required. */
public static final int FLASH_AUTO = Constants.FLASH_AUTO;
/** Flash will be fired in red-eye reduction mode. */
public static final int FLASH_RED_EYE = Constants.FLASH_RED_EYE;
/** The mode for for the camera device's flash control */
#IntDef({FLASH_OFF, FLASH_ON, FLASH_TORCH, FLASH_AUTO, FLASH_RED_EYE})
public #interface Flash {
}
CameraViewImpl mImpl;
private final CallbackBridge mCallbacks;
private boolean mAdjustViewBounds;
private final DisplayOrientationDetector mDisplayOrientationDetector;
public CameraView(Context context) {
this(context, null);
}
public CameraView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
#SuppressWarnings("WrongConstant")
public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (isInEditMode()){
mCallbacks = null;
mDisplayOrientationDetector = null;
return;
}
// Internal setup
final PreviewImpl preview = createPreviewImpl(context);
mCallbacks = new CallbackBridge();
if (Build.VERSION.SDK_INT < 21) {
mImpl = new Camera1(mCallbacks, preview);
} else if (Build.VERSION.SDK_INT < 23) {
mImpl = new Camera2(mCallbacks, preview, context);
} else {
mImpl = new Camera2Api23(mCallbacks, preview, context);
}
// Attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView, defStyleAttr,
R.style.Widget_CameraView);
mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, false);
setFacing(a.getInt(R.styleable.CameraView_facing, FACING_BACK));
String aspectRatio = a.getString(R.styleable.CameraView_aspectRatio);
if (aspectRatio != null) {
setAspectRatio(AspectRatio.parse(aspectRatio));
} else {
setAspectRatio(Constants.DEFAULT_ASPECT_RATIO);
}
setAutoFocus(a.getBoolean(R.styleable.CameraView_autoFocus, true));
setFlash(a.getInt(R.styleable.CameraView_flash, Constants.FLASH_AUTO));
a.recycle();
// Display orientation detector
mDisplayOrientationDetector = new DisplayOrientationDetector(context) {
#Override
public void onDisplayOrientationChanged(int displayOrientation) {
mImpl.setDisplayOrientation(displayOrientation);
}
};
}
#NonNull
private PreviewImpl createPreviewImpl(Context context) {
PreviewImpl preview;
if (Build.VERSION.SDK_INT < 14) {
preview = new SurfaceViewPreview(context, this);
} else {
preview = new TextureViewPreview(context, this);
}
return preview;
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!isInEditMode()) {
mDisplayOrientationDetector.enable(ViewCompat.getDisplay(this));
}
}
#Override
protected void onDetachedFromWindow() {
if (!isInEditMode()) {
mDisplayOrientationDetector.disable();
}
super.onDetachedFromWindow();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isInEditMode()){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
// Handle android:adjustViewBounds
if (mAdjustViewBounds) {
if (!isCameraOpened()) {
mCallbacks.reserveRequestLayoutOnOpen();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
final AspectRatio ratio = getAspectRatio();
assert ratio != null;
int height = (int) (MeasureSpec.getSize(widthMeasureSpec) * ratio.toFloat());
if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec));
}
super.onMeasure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
} else if (widthMode != MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
final AspectRatio ratio = getAspectRatio();
assert ratio != null;
int width = (int) (MeasureSpec.getSize(heightMeasureSpec) * ratio.toFloat());
if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(width, MeasureSpec.getSize(widthMeasureSpec));
}
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
heightMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
// Measure the TextureView
int width = getMeasuredWidth();
int height = getMeasuredHeight();
AspectRatio ratio = getAspectRatio();
if (mDisplayOrientationDetector.getLastKnownDisplayOrientation() % 180 == 0) {
ratio = ratio.inverse();
}
assert ratio != null;
if (height < width * ratio.getY() / ratio.getX()) {
mImpl.getView().measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(width * ratio.getY() / ratio.getX(),
MeasureSpec.EXACTLY));
} else {
mImpl.getView().measure(
MeasureSpec.makeMeasureSpec(height * ratio.getX() / ratio.getY(),
MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
}
#Override
protected Parcelable onSaveInstanceState() {
SavedState state = new SavedState(super.onSaveInstanceState());
state.facing = getFacing();
state.ratio = getAspectRatio();
state.autoFocus = getAutoFocus();
state.flash = getFlash();
return state;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setFacing(ss.facing);
setAspectRatio(ss.ratio);
setAutoFocus(ss.autoFocus);
setFlash(ss.flash);
}
/**
* Open a camera device and start showing camera preview. This is typically called from
* {#link Activity#onResume()}.
*/
public void start() {
if (!mImpl.start()) {
//store the state ,and restore this state after fall back o Camera1
Parcelable state=onSaveInstanceState();
// Camera2 uses legacy hardware layer; fall back to Camera1
mImpl = new Camera1(mCallbacks, createPreviewImpl(getContext()));
onRestoreInstanceState(state);
mImpl.start();
}
}
/**
* Stop camera preview and close the device. This is typically called from
* {#link Activity#onPause()}.
*/
public void stop() {
mImpl.stop();
}
/**
* #return {#code true} if the camera is opened.
*/
public boolean isCameraOpened() {
return mImpl.isCameraOpened();
}
/**
* Add a new callback.
*
* #param callback The {#link Callback} to add.
* #see #removeCallback(Callback)
*/
public void addCallback(#NonNull Callback callback) {
mCallbacks.add(callback);
}
/**
* Remove a callback.
*
* #param callback The {#link Callback} to remove.
* #see #addCallback(Callback)
*/
public void removeCallback(#NonNull Callback callback) {
mCallbacks.remove(callback);
}
/**
* #param adjustViewBounds {#code true} if you want the CameraView to adjust its bounds to
* preserve the aspect ratio of camera.
* #see #getAdjustViewBounds()
*/
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (mAdjustViewBounds != adjustViewBounds) {
mAdjustViewBounds = adjustViewBounds;
requestLayout();
}
}
/**
* #return True when this CameraView is adjusting its bounds to preserve the aspect ratio of
* camera.
* #see #setAdjustViewBounds(boolean)
*/
public boolean getAdjustViewBounds() {
return mAdjustViewBounds;
}
/**
* Chooses camera by the direction it faces.
*
* #param facing The camera facing. Must be either {#link #FACING_BACK} or
* {#link #FACING_FRONT}.
*/
public void setFacing(#Facing int facing) {
mImpl.setFacing(facing);
}
/**
* Gets the direction that the current camera faces.
*
* #return The camera facing.
*/
#Facing
public int getFacing() {
//noinspection WrongConstant
return mImpl.getFacing();
}
/**
* Gets all the aspect ratios supported by the current camera.
*/
public Set<AspectRatio> getSupportedAspectRatios() {
return mImpl.getSupportedAspectRatios();
}
/**
* Sets the aspect ratio of camera.
*
* #param ratio The {#link AspectRatio} to be set.
*/
public void setAspectRatio(#NonNull AspectRatio ratio) {
if (mImpl.setAspectRatio(ratio)) {
requestLayout();
}
}
/**
* Gets the current aspect ratio of camera.
*
* #return The current {#link AspectRatio}. Can be {#code null} if no camera is opened yet.
*/
#Nullable
public AspectRatio getAspectRatio() {
return mImpl.getAspectRatio();
}
/**
* Enables or disables the continuous auto-focus mode. When the current camera doesn't support
* auto-focus, calling this method will be ignored.
*
* #param autoFocus {#code true} to enable continuous auto-focus mode. {#code false} to
* disable it.
*/
public void setAutoFocus(boolean autoFocus) {
mImpl.setAutoFocus(autoFocus);
}
/**
* Returns whether the continuous auto-focus mode is enabled.
*
* #return {#code true} if the continuous auto-focus mode is enabled. {#code false} if it is
* disabled, or if it is not supported by the current camera.
*/
public boolean getAutoFocus() {
return mImpl.getAutoFocus();
}
/**
* Sets the flash mode.
*
* #param flash The desired flash mode.
*/
public void setFlash(#Flash int flash) {
mImpl.setFlash(flash);
}
/**
* Gets the current flash mode.
*
* #return The current flash mode.
*/
#Flash
public int getFlash() {
//noinspection WrongConstant
return mImpl.getFlash();
}
/**
* Take a picture. The result will be returned to
* {#link Callback#onPictureTaken(CameraView, byte[])}.
*/
public void takePicture() {
mImpl.takePicture();
}
private class CallbackBridge implements CameraViewImpl.Callback {
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
private boolean mRequestLayoutOnOpen;
CallbackBridge() {
}
public void add(Callback callback) {
mCallbacks.add(callback);
}
public void remove(Callback callback) {
mCallbacks.remove(callback);
}
#Override
public void onCameraOpened() {
if (mRequestLayoutOnOpen) {
mRequestLayoutOnOpen = false;
requestLayout();
}
for (Callback callback : mCallbacks) {
callback.onCameraOpened(CameraView.this);
}
}
#Override
public void onCameraClosed() {
for (Callback callback : mCallbacks) {
callback.onCameraClosed(CameraView.this);
}
}
#Override
public void onPictureTaken(byte[] data) {
for (Callback callback : mCallbacks) {
callback.onPictureTaken(CameraView.this, data);
}
}
public void reserveRequestLayoutOnOpen() {
mRequestLayoutOnOpen = true;
}
}
protected static class SavedState extends BaseSavedState {
#Facing
int facing;
AspectRatio ratio;
boolean autoFocus;
#Flash
int flash;
#SuppressWarnings("WrongConstant")
public SavedState(Parcel source, ClassLoader loader) {
super(source);
facing = source.readInt();
ratio = source.readParcelable(loader);
autoFocus = source.readByte() != 0;
flash = source.readInt();
}
public SavedState(Parcelable superState) {
super(superState);
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(facing);
out.writeParcelable(ratio, 0);
out.writeByte((byte) (autoFocus ? 1 : 0));
out.writeInt(flash);
}
public static final Parcelable.Creator<SavedState> CREATOR
= ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in, ClassLoader loader) {
return new SavedState(in, loader);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
});
}
/**
* Callback for monitoring events about {#link CameraView}.
*/
#SuppressWarnings("UnusedParameters")
public abstract static class Callback {
/**
* Called when camera is opened.
*
* #param cameraView The associated {#link CameraView}.
*/
public void onCameraOpened(CameraView cameraView) {
}
/**
* Called when camera is closed.
*
* #param cameraView The associated {#link CameraView}.
*/
public void onCameraClosed(CameraView cameraView) {
}
/**
* Called when a picture is taken.
*
* #param cameraView The associated {#link CameraView}.
* #param data JPEG data.
*/
public void onPictureTaken(CameraView cameraView, byte[] data) {
}
}
}
and xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorgrey">
<com.google.android.cameraview.CameraView
android:id="#+id/camera"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:background="#android:color/black" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<ImageButton
android:id="#+id/take_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:background="#0000"
app:srcCompat="#drawable/ic_take_pic" />
<ImageButton
android:id="#+id/btn_switch_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_margin="20dp"
android:background="#0000"
app:srcCompat="#drawable/ic_reset_camera" />
<ImageButton
android:id="#+id/btn_flash_onOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="20dp"
android:background="#0000"
app:srcCompat="#drawable/ic_flash_off" />
</RelativeLayout>
Also DONT FORGET TO ADD RUNTIME PERMISSIONS in OnCreate()

How to use matrix camera preview left and right reverse on android?

I want camera preview left and right reverse,
and I search for google, answer is use Matrix
is it right answer?
first, my source.
MainActivity.class
private Agen agen = null;
protected static Activity mainActivity = null;
#Override
protected void onCreate(final Bundle savedInstanceState) {
agen = new Agen();
agen.CameraSetting();
}
public static Activity getMainActivity() {
return mainActivity;
}
Agen.class
private CamLiveView camLiveView;
private final FrameLayout liveFrame;
private final Context context;
public Agen() {
Activity activity = MainActivity.getMainActivity();
context = activity;
liveFrame = (FrameLayout) activity.findViewById(R.id.liveview);
public boolean CameraSetting() {
boolean state = false;
try {
LiveCam livecam = CamManage.getInstance();
camLiveView = new CamLiveView(context, livecam, this);
if (liveFrame != null)
liveFrame.addView(camLiveView);
state = true;
} catch (Exception e) {
e.printStackTrace();
} return state;
}
CamManage.class
private static Camera mCamera = null;
public static LiveCam getInstance() {
if (mCamera == null) {
int cameras = Camera.getNumberOfCameras();
mCamera = Camera.open(0);
if (mCamera != null) {
mCamera.lock();
}
} else {
}
return getLiveCam();
}
getLiveCam
static private LiveCam getLiveCam() {
LiveCam livecam = new LiveCam() ;
Camera.Parameters params = mCamera.getParameters();
liveCam.preSize = params.getPreviewSize();
liveCam.preFormat = params.getPreviewFormat();
liveCam.camera = mCamera;
return liveCam;
}
LiveCam.class
public class LiveCam {
public Camera camera;
public Camera.Size preSize;
public int preFormat;
}
this my source.
but I don't know where use matrix part.
in other words, I want camera preview left and right reverse.
please advice for me
thanks.
add
public class CamLiveView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camer mCamera;
private int preWidth;
private int preHeight;
private int preFormat;
private boolean playing = false;
public CamLiveView(Context context, LiveCam livecam) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mCamera = livecam.camera;
preWidth = livecam.preSize.width;
preHeight = livecam.preSize.height;
preFormat = livecam.previewFormat;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
cameraPlay();
}
public boolean cameraPlay() {
if (mHolder == null)
return false;
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
playing = true;
} catch (Exception e) {
return false;
} return true;
}

SurfaceView not working inside PopupWindow

I gonna show a preview using a PopupWindow based on AirView feature of Samsung SPen
But the problem is that the SurfaceView is not created and non of the SurfaceHolder.Callback methods are called.
The surface region becomes transparent when the popup is displayed because the surface is not created at all.
SurfaceView is not created and is transparent:
HoverPreview:
public class HoverPreview extends LinearLayout implements View.OnHoverListener, SurfaceHolder.Callback {
private static final String TAG = "HoverPreview";
private SurfaceHolder mHolder = null;
View mAnchorView = null;
String videoPath;
int position;
private boolean IsMediaPlayerReady = false;
private MediaPlayer mMediaPlayer;
private SurfaceView mSurfaceView;
Context context;
public HoverPreview(Context context, String videoPath, int position) {
super(context);
this.videoPath = videoPath;
this.position = position;
setupLayout(context);
}
public HoverPreview(Context context, AttributeSet attrs) {
super(context, attrs);
setupLayout(context);
}
public HoverPreview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupLayout(context);
}
private void setupLayout(Context context) {
this.context = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.media_browser_hover, this);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface created");
final Surface surface = surfaceHolder.getSurface();
if (surface == null) return;
if (!surface.isValid()) return;
mHolder = surfaceHolder;
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(videoPath);
} catch (IOException e) {
e.printStackTrace();
}
mMediaPlayer.setDisplay(mHolder);
mAnchorView.setTag(mMediaPlayer);
mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mediaPlayer, int i, int i2) {
mHolder.setFixedSize(i, i2);
}
});
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "MediaPlayer preview is prepared");
IsMediaPlayerReady = true;
if (mMediaPlayer != null && IsMediaPlayerReady) {
if (position > 0)
mMediaPlayer.seekTo(position);
mMediaPlayer.start();
}
}
});
Log.d(TAG, "MediaPlayer is created");
try {
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
Log.d(TAG, "HoverSurface changed");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface destroyed");
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
//thumbnailImageView.setTag(null);
}
}
public void setAnchorView(View view) {
mAnchorView = view;
}
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
try {
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
Log.d(TAG, "ACTION_HOVER_ENTER");
mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);
mHolder = mSurfaceView.getHolder();
if (mHolder != null) {
mHolder.addCallback(this);
}
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "ACTION_HOVER_EXIT");
if (mAnchorView.getTag() != null) {
MediaPlayer mMediaPlayer = (MediaPlayer) mAnchorView.getTag();
mMediaPlayer.stop();
mMediaPlayer.release();
mAnchorView.setTag(null);
}
}
} catch (Exception e) {
Log.e(TAG, e.getMessage() + Utils.toString(e.getStackTrace()));
}
return false;
}
}
The code to show the preview:
final PopupWindow popupWindow = new PopupWindow(context);
final HoverPreview hoverPreview = new HoverPreview(context, videoPath, 0);
hoverPreview.setAnchorView(thumbnailImageView);
thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
hoverPreview.onHover(view, motionEvent);
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
popupWindow.setContentView(hoverPreview);
popupWindow.setWidth(600);
popupWindow.setHeight(400);
popupWindow.showAtLocation(thumbnailImageView, ToolHoverPopup.Gravity.NO_GRAVITY, 10, 10);
Log.d(TAG, "Manual Hover Enter");
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "Manual Hover Exit");
if (popupWindow != null)
popupWindow.dismiss();
}
return true;
});
Here's my complete working solution:
I borrowed some code from ToolHoverPopup class from SPen library, also I customized for this special popup so that nothing is created or inflated until the actual hovering is happened so that we don't consume resources for enabling such a preview in lists.
We need to have our preview attached to a Window so because of this we have to manage all the underlying job of positioning which is normally done by PopupWindow, so I completely removed the dependency on the PopupWindow and now my HoverPreview class is fully working and manages all the jobs, also it has the ability to determine the Hover Detection delay in milliseconds.
Screenshot (SurfaceView is created)
Usage: (Since the layout contains SurfaceView and is resource intensive, I manually trigger onHover event so that the real surface creation is performed only when the real hover is performed. Also by this, I don't create any object of HoverPreview before it's needed)
thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
HoverPreview hoverPreview;
if (thumbnailImageView.getTag() == null) {
hoverPreview = new HoverPreview(context, getActivity().getWindow(), videoPath, 0);
hoverPreview.setHoverDetectTime(1000);
thumbnailImageView.setTag(hoverPreview);
} else
hoverPreview = (HoverPreview) thumbnailImageView.getTag();
hoverPreview.onHover(null, motionEvent);
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT)
thumbnailImageView.setTag(null);
return true;
}
});
HoverPreview:
public class HoverPreview extends LinearLayout implements View.OnHoverListener, SurfaceHolder.Callback {
private static final int MSG_SHOW_POPUP = 1;
private static final int MSG_DISMISS_POPUP = 2;
private static final int HOVER_DETECT_TIME_MS = 300;
private static final int POPUP_TIMEOUT_MS = 60 * 1000;
protected int mHoverDetectTimeMS;
private static final String TAG = "HoverPreview";
private SurfaceHolder mHolder = null;
String videoPath;
int position;
private boolean IsMediaPlayerReady = false;
private MediaPlayer mMediaPlayer;
private SurfaceView mSurfaceView;
Context context;
private HoverPopupHandler mHandler;
Window window;
public HoverPreview(Context context, Window window, String videoPath, int position) {
super(context);
this.mHoverDetectTimeMS = HOVER_DETECT_TIME_MS;
this.videoPath = videoPath;
this.position = position;
this.window = window;
setupLayout(context);
}
private void setupLayout(Context context) {
this.context = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rootView = inflater.inflate(R.layout.media_browser_hover, this);
mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);
}
View rootView;
#Override
protected void onFinishInflate() {
super.onFinishInflate();
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface created");
final Surface surface = surfaceHolder.getSurface();
if (surface == null) return;
if (!surface.isValid()) return;
mHolder = surfaceHolder;
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(videoPath);
} catch (IOException e) {
e.printStackTrace();
return;
}
mMediaPlayer.setDisplay(mHolder);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "MediaPlayer preview is prepared");
IsMediaPlayerReady = true;
int videoWidth = mMediaPlayer.getVideoWidth();
int videoHeight = mMediaPlayer.getVideoHeight();
Point size = new Point();
int screenHeight = 0;
int screenWidth = 0;
Display display = getDisplay();
display.getSize(size);
screenWidth = size.x - (350 + 30); // margin + padding
screenHeight = size.y;
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mSurfaceView.getLayoutParams();
lp.width = screenWidth;
lp.height = (int) (((float) videoHeight / (float) videoWidth) * (float) screenWidth);
mSurfaceView.setLayoutParams(lp);
if (mMediaPlayer != null && IsMediaPlayerReady) {
if (position > 0)
mMediaPlayer.seekTo(position);
mMediaPlayer.start();
findViewById(R.id.media_browser_hoverRootFrameLayout).setVisibility(VISIBLE);
}
}
});
Log.d(TAG, "MediaPlayer is created");
try {
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
Log.d(TAG, "HoverSurface changed");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface destroyed");
try {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
} catch (Exception e) {
}
}
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
try {
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
Log.d(TAG, "ACTION_HOVER_ENTER");
show(); // checks the timing
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "ACTION_HOVER_EXIT");
dismiss();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage() + Utils.toString(e.getStackTrace()));
}
return false;
}
/**
* Sets the time that detecting hovering.
*
* #param ms The time, milliseconds
*/
public void setHoverDetectTime(int ms) {
mHoverDetectTimeMS = ms;
}
public void dismiss() {
dismissPopup();
}
private void dismissPopup() {
// remove pending message and dismiss popup
getMyHandler().removeMessages(MSG_SHOW_POPUP);
getMyHandler().removeMessages(MSG_DISMISS_POPUP);
try {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
} catch (Exception e) {
}
if (getParent() != null)
((ViewGroup) getParent()).removeView(this);
}
private Handler getMyHandler() {
if (mHandler == null)
mHandler = new HoverPopupHandler();
return mHandler;
}
public void show() {
// send message to show.
if (getMyHandler().hasMessages(MSG_SHOW_POPUP)) {
return;
// getHandler().removeMessages(MSG_SHOW_POPUP);
}
getMyHandler().sendEmptyMessageDelayed(MSG_SHOW_POPUP, mHoverDetectTimeMS);
}
private void showPopup() {
if (getParent() == null) {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER_VERTICAL;
params.x = 350;
window.addContentView(this, params);
}
mHolder = mSurfaceView.getHolder();
if (mHolder != null) {
mHolder.addCallback(this);
}
}
;
private class HoverPopupHandler extends Handler {
#Override
public void handleMessage(Message msg) {
// if (DEBUG)
// android.util.Log.e(TAG, "handleMessage : " + ((msg.what == MSG_SHOW_POPUP) ? "SHOW" : "DISMISS"));
switch (msg.what) {
case MSG_SHOW_POPUP:
showPopup();
sendEmptyMessageDelayed(MSG_DISMISS_POPUP, POPUP_TIMEOUT_MS);
break;
case MSG_DISMISS_POPUP:
dismissPopup();
break;
}
}
}
}

Simultaneous TextureView and SurfaceView Android Camera

I can display a preview of the camera video properly with a TextureView:
package com.example.camerasurfacetexture;
import java.io.IOException;
import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.widget.FrameLayout;
public class MainActivity extends Activity implements SurfaceTextureListener
{
private Camera mCamera = null;
private TextureView mTextureView = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(this);
setContentView(mTextureView);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
int height)
{
Log.i("onSurfaceTextureAvailable", "onSurfaceTextureAvailable");
mCamera = Camera.open();
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
previewSize.width, previewSize.height, Gravity.CENTER));
try
{
mCamera.setPreviewTexture(surface);
}
catch (IOException t)
{
}
mCamera.startPreview();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height)
{
// Ignored, the Camera does all the work for us
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
{
Log.i("onSurfaceTextureDestroyed", "onSurfaceTextureDestroyed");
mCamera.stopPreview();
mCamera.release();
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
{
// Update your view here!
}
}
and with a SurfaceView:
package com.example.cameratest;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
public class MainActivity extends Activity
{
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
private boolean cameraConfigured = false;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
preview = (SurfaceView) findViewById(R.id.cpPreview);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void onResume()
{
super.onResume();
camera = Camera.open();
startPreview();
}
#Override
public void onPause()
{
if (inPreview)
{
camera.stopPreview();
}
camera.release();
camera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters)
{
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if (size.width <= width && size.height <= height)
{
if (result == null)
{
result = size;
}
else
{
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea)
{
result = size;
}
}
}
}
return (result);
}
private void initPreview(int width, int height)
{
if (camera != null && previewHolder.getSurface() != null)
{
try
{
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t)
{
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(MainActivity.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
if (!cameraConfigured)
{
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
if (size != null)
{
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
cameraConfigured = true;
}
}
}
}
private void startPreview()
{
if (cameraConfigured && camera != null)
{
camera.startPreview();
inPreview = true;
}
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback()
{
public void surfaceCreated(SurfaceHolder holder)
{
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// no-op
}
};
}
but if I try to do both at the same time:
package com.example.multiplecamerapreviewtest;
import java.io.IOException;
import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.widget.FrameLayout;
import android.widget.Toast;
public class MainActivity extends Activity implements SurfaceTextureListener
{
private SurfaceView svPreview = null;
private SurfaceHolder previewHolder = null;
private Camera mCamera = null;
private boolean inPreview = false;
private boolean cameraConfigured = false;
private TextureView tvPreview = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
svPreview = (SurfaceView) findViewById(R.id.svPreview);
previewHolder = svPreview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// mTextureView = new TextureView(this);
tvPreview = (TextureView) findViewById(R.id.tvPreview);
tvPreview.setSurfaceTextureListener(this);
// setContentView(mTextureView);
}
#Override
public void onResume()
{
super.onResume();
mCamera = Camera.open();
startPreview();
}
#Override
public void onPause()
{
if (inPreview)
{
mCamera.stopPreview();
}
mCamera.release();
mCamera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters)
{
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if (size.width <= width && size.height <= height)
{
if (result == null)
{
result = size;
}
else
{
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea)
{
result = size;
}
}
}
}
return (result);
}
private void initPreview(int width, int height)
{
if (mCamera != null && previewHolder.getSurface() != null)
{
try
{
mCamera.setPreviewDisplay(previewHolder);
}
catch (Throwable t)
{
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(MainActivity.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
if (!cameraConfigured)
{
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
if (size != null)
{
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
cameraConfigured = true;
}
}
}
}
private void startPreview()
{
if (cameraConfigured && mCamera != null)
{
mCamera.startPreview();
inPreview = true;
}
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback()
{
public void surfaceCreated(SurfaceHolder holder)
{
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// no-op
}
};
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
int height)
{
Log.i("onSurfaceTextureAvailable", "onSurfaceTextureAvailable");
mCamera = Camera.open();
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
tvPreview.setLayoutParams(new FrameLayout.LayoutParams(
previewSize.width, previewSize.height, Gravity.CENTER));
try
{
mCamera.setPreviewTexture(surface);
}
catch (IOException t)
{
}
mCamera.startPreview();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height)
{
// Ignored, the Camera does all the work for us
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
{
Log.i("onSurfaceTextureDestroyed", "onSurfaceTextureDestroyed");
mCamera.stopPreview();
mCamera.release();
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
{
// Update your view here!
}
}
I get a "Fail to connect to camera service" exception when calling mCamera.setPreviewTexture().
According to the documentation (http://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay%28android.view.SurfaceHolder%29), this is the expected behavior:
setPreviewDisplay()
Setting a preview surface will un-set any preview surface texture that was set via setPreviewTexture(SurfaceTexture).
(and vice-versa). Is there anything I can do to get these both displaying at the same time?
Send the Camera output to a SurfaceTexture, then render the texture wherever you like using GLES.
See e.g. the "texture from camera" activity in Grafika.
This requires some EGL management and a basic familiarity with GLES, though you can get pretty far just using the code in Grafika. This approach will get you much better performance than manipulating pixels with the NDK, because the GPU does all the work.
Camera is a shared hardware resource. I don't think you can access it (Camera.open()) more than once even within the same application i.e even within the same process with same user id. How about accessing the buffers for camera preview natively and then reading bytes from those buffers to render them on as many TextureViews or SurfaceViews or VideoViews as you wish?
Edited:
NDK Resource:
How do I get the raw Android camera buffer in C using JNI?

how to put a picture to front of a camera preview

I would like to make an app that have 2 activities. The first one is a CameraPreview from api demos that have an options menu by default. I added to it a second button that starts the second activity, what is a ImageSwitcher. I want to give back the selected photo to front of the preview at a specified width and height.
This block is fine for get and appear a photo in a plain activity's onCreate method, but I don't know how to do this with a CameraPreview:
setContentView(R.layout.picturelay);
int theID = getIntent().getExtras().getInt("the_image_id");
ImageView i = (ImageView) findViewById(R.id.cameralay);
i.setImageResource(theID);
My starting activity:
public class CameraPreview extends Activity {
private
Preview mPreview;
Camera mCamera;
int numberOfCameras;
int cameraCurrentlyLocked;
String uzenet;
// The first rear facing camera
int defaultCameraId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Create a RelativeLayout container that will hold a SurfaceView,
// and set it as the content of our activity.
mPreview = new Preview(this);
setContentView(mPreview);
try {
int theID = getIntent().getExtras().getInt("the_image_id");
ImageView i = (ImageView) findViewById(R.id.cameralay);
i.setImageResource(theID);
} catch (Exception e){
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG);
}
// Find the total number of cameras available
numberOfCameras = Camera.getNumberOfCameras();
// Find the ID of the default camera
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
defaultCameraId = i;
}
}
}
#Override
protected void onResume() {
super.onResume();
// Open the default i.e. the first rear facing camera.
mCamera = Camera.open();
cameraCurrentlyLocked = defaultCameraId;
mPreview.setCamera(mCamera);
}
#Override
protected void onPause() {
super.onPause();
// Because the Camera object is a shared resource, it's very
// important to release it when the activity is paused.
if (mCamera != null) {
mPreview.setCamera(null);
mCamera.release();
mCamera = null;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate our menu which can gather user input for switching camera
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.camera_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.switch_cam:
// check for availability of multiple cameras
if (numberOfCameras == 1) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(this.getString(R.string.camera_alert))
.setNeutralButton("Close", null);
AlertDialog alert = builder.create();
alert.show();
return true;
}
// OK, we have multiple cameras.
// Release this camera -> cameraCurrentlyLocked
if (mCamera != null) {
mCamera.stopPreview();
mPreview.setCamera(null);
mCamera.release();
mCamera = null;
}
// Acquire the next camera and request Preview to reconfigure
// parameters.
mCamera = Camera
.open((cameraCurrentlyLocked + 1) % numberOfCameras);
cameraCurrentlyLocked = (cameraCurrentlyLocked + 1)
% numberOfCameras;
mPreview.switchCamera(mCamera);
// Start the preview
mCamera.startPreview();
return true;
case R.id.get_picture:
Intent intent2 = new Intent(CameraPreview.this, ImageSwitcher1.class);
//startActivityForResult(intent, 0);
startActivity(intent2);
return true;
}
return super.onOptionsItemSelected(item);
}
}
class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
Preview(Context context) {
super(context);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
}
public void switchCamera(Camera camera) {
setCamera(camera);
try {
camera.setPreviewDisplay(mHolder);
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
camera.setParameters(parameters);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
The second activity:
public class ImageSwitcher1 extends Activity implements
AdapterView.OnItemSelectedListener, ViewSwitcher.ViewFactory {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.image_switcher_1);
mSwitcher = (ImageSwitcher) findViewById(R.id.switcher);
mSwitcher.setFactory(this);
mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_in));
mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_out));
Gallery g = (Gallery) findViewById(R.id.gallery);
g.setAdapter(new ImageAdapter(this));
g.setOnItemSelectedListener(this);
g.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
Intent intent = new Intent(ImageSwitcher1.this, CameraPreview.class);
intent.putExtra("the_image_id", mImageIds[position]);
startActivity(intent);
finish();
}
});
}
public void onItemSelected(AdapterView parent, View v, int position, long id) {
mSwitcher.setImageResource(mImageIds[position]);
}
public void onNothingSelected(AdapterView parent) {
}
public View makeView() {
ImageView i = new ImageView(this);
i.setBackgroundColor(0xFF000000);
i.setScaleType(ImageView.ScaleType.FIT_CENTER);
i.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
return i;
}
private ImageSwitcher mSwitcher;
public class ImageAdapter extends BaseAdapter {
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageResource(mThumbIds[position]);
i.setAdjustViewBounds(true);
i.setLayoutParams(new Gallery.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
i.setBackgroundResource(R.drawable.picture_frame);
return i;
}
private Context mContext;
}
private Integer[] mThumbIds = {
R.drawable.1, R.drawable.2,
R.drawable.3, R.drawable.4,
R.drawable.5, R.drawable.6,
R.drawable.7, R.drawable.8,
R.drawable.9
};
private Integer[] mImageIds = {
R.drawable.1, R.drawable.2,
R.drawable.3, R.drawable.4,
R.drawable.5, R.drawable.6,
R.drawable.7, R.drawable.8,
R.drawable.9
};
}
Thank You for your replies!
I had a solution with a different Preview activity. So I can see the selected image front of the camera preview. This is the used preview activity:
public class PreviewDemo extends Activity {
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
private Camera camera=null;
private boolean inPreview=false;
private boolean cameraConfigured=false;
private Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview=(SurfaceView)findViewById(R.id.preview);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
try {
int theID = getIntent().getExtras().getInt("the_image_id");
ImageView i = (ImageView) findViewById(R.id.cameralay);
i.setImageResource(theID);
} catch (Exception e){
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG);
}
}
#Override
public void onResume() {
super.onResume();
camera=Camera.open();
startPreview();
}
#Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera=null;
inPreview=false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width<=width && size.height<=height) {
if (result==null) {
result=size;
}
else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return(result);
}
private void initPreview(int width, int height) {
if (camera!=null && previewHolder.getSurface()!=null) {
try {
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast
.makeText(PreviewDemo.this, t.getMessage(), Toast.LENGTH_LONG)
.show();
}
if (!cameraConfigured) {
Camera.Parameters parameters=camera.getParameters();
Camera.Size size=getBestPreviewSize(width, height,
parameters);
if (size!=null) {
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
cameraConfigured=true;
}
}
}
}
private void startPreview() {
if (cameraConfigured && camera!=null) {
camera.startPreview();
inPreview=true;
}
}
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width,
int height) {
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate our menu which can gather user input for switching camera
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.camera_menu2, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.take_photo:
//code of taking a photo will be here...
return true;
}
return super.onOptionsItemSelected(item);
}
}
And my layout file that contains the surface view and image view:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.view.SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/preview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.view.SurfaceView>
<ImageView
android:id="#+id/cameralay"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:contentDescription="#+id/app_name">
</ImageView>
</RelativeLayout>

Categories

Resources