I am currently coding an Android application on android studio with Java. This one is simple, when the button is clicked, a series of flashing of the phone's torch is launched. I need each flash to be regulated, and last the same time, but it's not the case, each flash does not last the same.
For this code, for example, we have 150 loops of 400 milliseconds, so we should have 150*0.4=60 seconds of operation, but by timing, I have about 65 seconds, certainly because of the inprecision of the duration of each flash.
I wanted to know if anyone has an idea, how to solve this problem,
Thanks in advance.
private void switchOn(){ // Function that is called each time the user presses the button (Onclick )
for (int i=0; i<150; i++){
flash(); // It calls the function that turns the torch on or off
try {
Thread.sleep(200); // process that puts a delay and allows the torch to work 200 milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
flash();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void flash(){ // function that turns the torch on or off according to its state
try {
CameraManager cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
for (String id : cameraManager.getCameraIdList()) {
if (cameraManager.getCameraCharacteristics(id)
.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
cameraManager.setTorchMode(id, !flashState);
flashState = !flashState;
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
Related
I am trying to make a music streaming app. For the music I use a URL, and for some reason, the music is playing for 3 seconds and then automatically stops. pls help me fix it.
I also get a message in the Run says: "MediaPlayer finalized without being released".
Thanks.
the code:
String url = "https://radio.streamgates.net/stream/1036kh"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
try {
mediaPlayer.setDataSource(url);
} catch (IOException e) {
Toast.makeText(this,"failed", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
try {
mediaPlayer.prepare(); // might take long! (for buffering, etc)
} catch (IOException e) {
Toast.makeText(this,"failed", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
mediaPlayer.start();
I'm trying to disable auto-exposure, auto-focus, and auto-white-balance in Google's Camera2Basic sample. Here's my code:
private void disableAutomatics() {
try {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE_OFF);
mPreviewRequestBuilder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_OFF);
mPreviewRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, .2f);
mPreviewRequestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 1000000L);
mPreviewRequest = mPreviewRequestBuilder.build();
// Set new repeating request with our changed one
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
The problem is I don't know where to place the method in Camera2BasicFragment.java.
Any help would be greatly appreciated.
There are two places where you may want to do those settings:
If you want to do it before the preview starts, the better place would be inside of the overridden method onConfigured within the createCameraPreviewSession() void (line 696 in the Camera2BasicFragment file provided in the Google's Camera2Basic sample:
private void createCameraPreviewSession() {
try {
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
// We set up a CaptureRequest.Builder with the output Surface.
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
// Here, we create a CameraCaptureSession for camera preview.
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
//Place here your custom camera settings
// Start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
showToast("Failed");
}
}, null
);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
If you want to do the settings after the preview has started and in runtime just call your disableAutomatics() from the UI or anywhere else and it should work fine.
Note that you don't have to close the older CaptureSession by calling its CaptureSession.close() method as explained in an answer to this other question because the new replaces the older one.
On another hand, I am not sure about setting the exposure time value manually as you did in your question:
mPreviewRequestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 1000000L);
because you may get unexpected results varying on different devices. What I know is that doing so is usually discouraged and it's preferred instead to let the camera adjust by its own and then call AE (auto-exposure) lock:
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
You can check the CONTROL_AE_LOCK reference here.
But if your code needs a fixed exposure time then it should work.
The problem I am having at the moment is that my pause is not always working.
What I have is an MediaPlayer in main activity that is operated via ActionBarSherlock and onClick listeners. MediaPlayer is using ArrayList with URLs of MP3 files(some of them 1sec long).
Pause code:
if (player.isPlaying()) {
if (player != null) {
player.pause();
swapPlayIcon(1);
isPaused = true;
pauseMenuButt.setVisible(false);
playMenuButt.setVisible(true);
}
}
swapPlayIcon(int) handles only visibility and drawable swaps.
Start code:
Iterator<Uri> iterUri = tracks.iterator();
while (iterUri.hasNext()) {
Uri tmpUri = iterUri.next();
try {
player.reset();
player.setDataSource(String.valueOf(tmpUri));
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
EDIT
After more testing I have found out that the problem appear in "in between" state.
What I mean is that when my MP3 file is 2sec long and I click pause its not stopping becouse it just have ended reading one file and now moved on to the next one.
I have added:
} else {
pauseLocked = true;
}
to pause if statment and it does not land in it at all while testing.
So im not sure about the "in between" problem that I have found out previously.
Your pause button is not working because there's no way for its message to ever reach the MediaPlayer until you've started the last URL. You are entirely blocking the thread your MediaPlayer is running on (I'm assuming it's the UI thread since the MediaPlayer is in your main activity). If you're creating your MediaPlayer on the same thread as your UI, you should use the asynchronous version of prepare: prepareAsync. You need to respond once you receive the onMediaPrepared callback and then start the media. Once that happens you must do nothing and wait for the media to finish, only then should you load another url.
I am trying to make camera application which takes 3 continuous shots.
i have tried to call "takePicture" several times by putting it in a loop.
but no success.
please help on this matter.
a little help will be appreciated.
You never should call PictureCallback.onPictureTaken() from your code; this callback receives data from the system when it is ready, as response to Camera.takePicture().
The latter call will only succeed if the camera is opened and preview is started. Therefore, simply calling Camera.takePicture() in a loop will not work (see e.g. Android 2.3.1 Camera takePicture() Multiple images with one button click). The correct way to handle this is to keep a counter of shots processed in your onPictureTaken(), and if it is less than 3, then restart camera preview and issue (synchroneously) another Camera.takePicture(). After this, onPictureTaken() should return, to allow processing of the next captured frame.
I use it like this when doing a PhotoBurst. It is also handling the FRameLayout holding the preview to start the PhotoBurst:
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
Parameters param = camera.getParameters();
param.setPictureSize(640, 480);
camera.setParameters(param);
// Or write to sdcard
outStream = new FileOutputStream(String.format(
Environment.getExternalStorageDirectory().getPath()+"/foto%d.jpg",
System.currentTimeMillis()));
outStream.write(data);
outStream.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.fromFile(Environment.getExternalStorageDirectory())));
Log.i(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpg");
try {
stillCount++;
camera.startPreview();
if (stillCount < 10) {
preview.mCamera.takePicture(shutterCallback, rawCallback,
jpegCallback);
if (stillCount == 9) {
frameLayout.setClickable(true);
}
} else {
stillCount = 0;
takePictureButton.setEnabled(true);
frameLayout.setClickable(true);
}
} catch (Exception e) {
Log.d(TAG, "Error starting preview: " + e.toString());
}
}
};
I got the solution.
i was calling mCamera.startPreview(); out of my loop.
preview is must to take shots, and not including mCamera.startPreview(); was blocking my execution.
I have some code I have been experimenting with to see what I can do with the camera device. This following code works, but I have some issues with it that I cannot seem to solve.
The first call never works. The first time running the code the onPictureTaken callback is never called, so the file is never written. However the camera goes through all the other steps, including making the fake shutter noise.
I can't seem to set the picture size to something other than whatever it defaults to. If I try to set it to something else, the code stops working. Does the same as above, where the camera goes through all the motions, but the onPictureTaken callback is never called.
When the pictures are saved to the DCIM folder, the taken pictures do not show up in the default 'Photos' app on my phone, unless i reboot the phone.
Is there any way through code to disable the shutter noise?
Sorry, the code is a little messy because its an experiment.
Also, this code is executed in a BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals(TAKE_PICTURE_INTENT))
{
Toast.makeText(context, "Test", Toast.LENGTH_LONG).show();
System.out.println("GOT THE INTENT");
try
{
Camera camera = Camera.open();
System.out.println("CAMERA OPENED");
Parameters params = camera.getParameters();
params.set("flash-mode", "off");
params.set("focus-mode", "infinity");
params.set("jpeg-quality", "100");
//params.setPictureSize(2592, 1952);
String str = params.get("picture-size" + "-values");
System.out.println(str);
String size = str.split(",")[0];
System.out.println(size);
//params.set("picture-size", size);
camera.setParameters(params);
System.out.println("CAMERA PARAMETERS SET");
camera.startPreview();
System.out.println("CAMERA PREVIEW STARTED");
camera.autoFocus(new AutoFocusCallBackImpl());
}
catch(Exception ex)
{
System.out.println("CAMERA FAIL, SKIP");
return ;
}
}//if
}//onreceive
private void TakePicture(Camera camera)
{
camera.takePicture(new Camera.ShutterCallback() {
#Override
public void onShutter() {
// TODO Auto-generated method stub
System.out.println("CAMERA SHUTTER CALLBACK");
}
}
, null,
new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
//c.release();
System.out.println("CAMERA CALLBACK");
FileOutputStream outStream = null;
try {
System.out.println("Start Callback");
File esd = Environment.getExternalStorageDirectory();
outStream = new FileOutputStream(esd.getAbsolutePath() + String.format(
"/DCIM/%d.jpg", System.currentTimeMillis()));
outStream.write(imageData);
outStream.close();
System.out.println( "onPictureTaken - wrote bytes: " + imageData.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("File not found exception");
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO exception");
} finally {
System.out.println("Finally");
c.release();
}
}
}
);
//camera.release();
}//TAKE PICTURE
private class AutoFocusCallBackImpl implements Camera.AutoFocusCallback {
#Override
public void onAutoFocus(boolean success, Camera camera) {
//bIsAutoFocused = success; //update the flag used in onKeyDown()
System.out.println("Inside autofocus callback. autofocused="+success);
//play the autofocus sound
//MediaPlayer.create(CameraActivity.this, R.raw.auto_focus).start();
if(success)
{
System.out.println("AUTO FOCUS SUCCEDED");
}
else
{
System.out.println("AUTO FOCUS FAILED");
}
TakePicture(camera);
System.out.println("CALLED TAKE PICTURE");
}
}//AUTOFOCUSCALLBACK
1.First of all put all camera logic out of BroadCast receiver & put it into seprate Activity.
2.
When the pictures are saved to the DCIM folder, the taken pictures do not show up in the default 'Photos' app on my phone, unless i reboot the phone.
because MediaScanner needs to be called to rescan images/changes once you take photo. When u reboot phone mediascanner scans media & finds new images. for this isuue you should check out MediaScanner.
3.Follow Android Camera Tutorial & Camera API
-Thanks