How to switch front/back camera in Android by GLSurfaceView? - android

I have posted an issue to grafika, but it seems there is nobody to maintain the project now.
I want to use the CameraCaptureActivity which implemented by GLSurfaceView to switch front/back camera, as following:
public boolean switchCamera() {
releaseCamera();
mGLView.onPause();
if (mReqCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
mReqCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
} else {
mReqCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
}
openCamera(mReqCameraId);
mGLView.onResume();
mGLView.queueEvent(new Runnable() {
#Override
public void run() {
mRenderer.setCameraPreviewSize(mCameraPreviewWidth, mCameraPreviewHeight);
}
});
return true;
}
It can work, but the FOV has been changed when I back to the camera which first time launched. It seems the frame has been clipped.
So where did i miss when switch the front-back camera?
Thanks.
PS: I have googled, but there is little information about Android Camera with GLSurfaceView.

As #fadden's comment, i remove the setRecordingHint(true), and it works fine.

Related

Android media recording and unhandled events

Hi I am using android with java. I have set up a very simple button which when held down records audio and when released stops recording. I have two questions:
When I run the following implementation of my idea, I get runtime a warning mediarecorder went away with unhandled events every time the button is released. I can't find what is causing this! I see that this has been answered previously on this forum many years ago with the suggestion to add mediaRecorder.update(), but this does not address why the warning is occurring. What does it mean by unhandled events and what could be causing it? I have done nothing different I can see than in the documentation, other than using an onTouchListener...
Second, should I be wary of user's being able to switch on and off the button very rapidly - could this cause runtime problems and should I take steps to guard against this?
The relevant code I use is more-or-less this:
public void set() {
View.OnTouchListener recordOnTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if (requestMultiplePermissions(Permissions).granted) {
audioSetup();
recordAudio();
}
return true;
case MotionEvent.ACTION_UP:
stopAudio();
return true;
default:
return false;
}
}
binding.addnewvocabRecordVocab.setOnTouchListener(recordOnTouchListener)
}
where
private void audioSetup() {
File filedir = new File(filepath);
if (!filedir.exists()) {filedir.mkdirs();
file = new File(filepath,filename);
if (file.exists()) { file.delete();}
}
public void recordAudio () {
isRecording = true;
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
try {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(file);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.prepare();
} catch (Exception e) {
e.printStackTrace();
}
mediaRecorder.start();
}
public void stopAudio () {
if (isRecording) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
isRecording = false;
}
}
This isn't a full answer to my own question, and the question still stands. But after playing with this a while, I have learnt a few lessons.
If the user taps the record button for a second, then mediarecorder.stop() will produce an error if there is not sufficient data recorded. See this. So if one wants to prevent the app from crashing, one needs to wrap mediarecorder.stop() in some catch - as the discussion in the link advises us. In fact, on some shortish taps, the stop method seems to take rather a long time (well over a second), so it might be worth considering disabling the button just before and after the stop method is called.
Another problem with fast repeated tapping is that it seems to keep adding to the main thread queue, which is probably inadvisable. I have found that using an executor thread with submit is a nice way of dealing with this. Schematically we can
public class audioLibrary() {
//or could go directly in main code
ExecutorService executor;
public void onStartRecord() {
if (executor == null) {
this.executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
//check isRecording and record stuff
});
}
}
public void onStopRecord() {
if (executor != null) {
executor.submit(() -> {
//check isRecording and shut down mediarecorder
//together with catch for onStop.
});
executor.shutdown();
}
}
}
Clearly, one must be a little careful to make sure the thread really does always get shut down.
Curiously, I do not get the `unhandled events' when I do this now...
Maybe someone could expand on this and comment on my code above to see whether they agree with the gist of it, whether it is necessary and on possible improvements.

How to keep the flashlight on (programmatically) while the camera preview is ON

So for my Android app, I have created a SurfaceView and assigned it as camera preview and start camera preview using the necessary API's. But now I want to turn the Flashlight ON (kind of act like a Torch) while the preview is working.
Please note that I have seen tons of examples online on how to turn flashlight on and it works as long as I don't call the open camera API. Below is the code -
try
{
CameraManager cameraManager = (CameraManager)context.GetSystemService(Context.CameraService);
if (cameraManager != null)
{
//for the sake of brevity, hardcoded the camera id. 0 is mostly back camera
cameraManager.SetTorchMode(0, true);
}
}
catch (CameraAccessException e)
{
LogUtil.Error("CameraInput", e.ToString());
}
Please note I am testing on Android N and hence the above code works flawlessly. But as soon as I call below line of code, the flash turns off.
Camera camera = Camera.Open(0);
// ...... some code ....//
camera.StartPreview();
When the above 2 lines execute, the flash goes off. Is this a know behaviour like where camera takes exclusive lock over flash hardware and resets it's value to default.
I tried reversing the above code i.e calling the Camera Open API being called first and then setting the flash. On that I get CameraAccessException , camera already in use.
What am i missing ?
Try this while previewing on SurfaceView
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_ON);
camera.setParameters(params);
Remember that If you want to use it as flashlight you can do:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
If not, to turn flash on which will come out when you take the picture, you use:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
Happy Coding!
Figured out how to torch on and off while camera is previewing. On button click to on/off the light, use this code:
//at some other function where camera is initialised and start preview
//...
Camera camera = Camera.open();
camera.startPreview();
//...
boolean lightOn = false;
//...
buttonLight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Camera.Parameters p = camera.getParameters();
if (!lightOn) {
lightOn = true;
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
} else {
lightOn = false;
p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
}
}
});
Happy Coding! :D

Android Live Wallpaper crashes when tap on camera

I have a live wallpaper that just draws triangles, very simple, and runs smoothly all time. After testing found that when I open the camera to take pictures the phone freezes for about 10 seconds, then the camera opens and the wallpaper crashes and the message "Unfortunately, Live Wallpaper has stopped." appears. Also found that when I open any barcode scanner app the problem raises again because the scanner uses the camera too. Seems the problem raises when the camera app runs. Any ideas what's causing it?
hi #Bullet Camera is just open ones, if it open through any other apps then, you can can not access your camera, Solution is that, where you use camera please release that after no used.
main problem is that, in your app (app in that you are using camera) , so , you release camera after used.
like following :
#Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
when you need
private void releaseCameraAndPreview() {
if (camera != null) {
camera.release();
camera = null;
}
}
or
public void stopCamera() {
if (cameraDevice != null) {
cameraDevice.stopPreview();
cameraDevice.setPreviewCallback(null);
cameraDevice.release();
cameraDevice = null;
System.out.println("in to the stop video");
}
}

Google GDK: Differences in calling app with voice trigger or menu affecting camera service?

I'm trying to create a Glass GDK app that uses the Camera service to show a preview. Unfortunately, I currently have a bug where a RuntimeException is thrown when trying to open a Camera using Camera.open(). I only encounter this bug when opening the activity through a voice trigger, not by selecting the app from the "launcher" menu.
Is there a difference in how an Activity is launched through this menu versus the voice trigger?
Some of the relevant code is below.
#Override
public void onCreate(Bundle savedInstanceState) {
mGestureDetector = createGestureDetector(this);
super.onCreate(savedInstanceState);
ctx = this;
act = this;
setContentView(R.layout.activity_main);
preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView));
((FrameLayout) findViewById(R.id.preview)).addView(preview);
preview.setKeepScreenOn(true);
}
#Override
protected void onResume() {
super.onResume();
try {
if (camera == null) {
Log.d(TAG, "Opening a camera on resume.");
camera = Camera.open();
preview.setCamera(camera);
camera.startPreview();
}
} catch(java.lang.RuntimeException e) {
Log.e(TAG, e.getMessage());
}
}
#Override
protected void onPause() {
if(camera != null) {
camera.stopPreview();
preview.setCamera(null);
Log.d(TAG, "Releasing a camera on pause.");
camera.release();
camera = null;
}
super.onPause();
}
#Override
protected void onDestroy() {
if(camera != null) {
camera.stopPreview();
preview.setCamera(null);
Log.d(TAG, "Releasing a camera on destory.");
camera.release();
camera = null;
}
super.onDestroy();
}
Since it doesn't work when using the voice trigger, it sounds like a possible race condition where the microphone isn't released by the time your activity is displayed on the screen.
Can you try an approach that uses exponential back-off to capture the camera? Basically try to capture the camera and if you get an exception, try again after a short amount of time, increasing the wait time slightly for a fixed number of attempts.
Please also consider filing a bug on the issue tracker, especially if you can reliably find out how much of a delay is needed before the camera/mic can be acquired.
The problem is caused by the delay between the voice recogniser closing event and the camera open event, which is causing a memory overload.
To avoid the problem when launching the app which will be triggered with voice,
pause the app for certain time (1000 Milli seconds will do) from opening the camera soon.
In the below code I am delaying my QR scanner to open from opening for 1000 Milli seconds. This works fine for me. If you want a you can increase the time interval.
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
intent = new Intent("com.google.zxing.client.android.SCAN");
startActivityForResult(intent, 0);
}
};
// sleeper time
handler.sendEmptyMessageDelayed(0, 1000);

Android: camera's startPreview method not working after stopPreview

In my application i have an image button that basically switches on and off the flash LED. The code is running fine for the first time i.e. On first Click it Switches On the LED and on the Second Click it Switches it Off. But then Nothing happens third Click onwards. I am testing this on Nexus S.
Following is the Code for the ImageButton Click Method.
public void ToggleTorch(){
final ImageButton tt = (ImageButton)findViewById(R.id.tt);
tt.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
if (isFlashOn){
mycam.stopPreview();
isFlashOn = false;
} else {
mycam.startPreview();
isFlashOn = true;
}
}
});
}
From what i think, it has to do something with the SurfaceView as i think it is not being destroyed while calling stopPreview but i am not sure..
Following is the Code for the onCreate Method.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Check if Flash Light is Available
Boolean has_flash = this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if(has_flash){
setContentView(R.layout.activity_main);
SurfaceView preview = (SurfaceView)findViewById(R.id.pSv);
SurfaceHolder holder = preview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
disableSleepMode();
initFlashLight();
ToggleTorch();
screenTorchOn();
} else {
setContentView(R.layout.activity_main);
disableSleepMode();
screenTorchOn();
}
}
any help would be appreciated. Thanks.
instead of calling stop preview release camera and make camera instance null. To restart camera, initialize camera again. Make two different method one for initialize camera and another to release it. This will solve your problem.

Categories

Resources