I want to write application which will be used camera flash. I want the light to blink. For now I have this code:
void ledon() {
cam = Camera.open();
Parameters params = cam.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_ON);
cam.setParameters(params);
cam.startPreview();
cam.autoFocus(new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
}
});
}
this part:
cam.autoFocus(new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
}
});
I dont know why its necessary but it wont work without it.
This code turn on led and turn off automaticly for about 2 seconds. I want to led will turn on e.g. for 5 sec then 3 sec led off and then again on for 4 seconds. How I can manually set periods of time in which led will be on and off. Is this possible? Thanks for any help.
PS. I have samsung galaxy ace.
it seems like what you want to use is Parameters.FLASH_MODE_TORCH. You set it to TORCH when you want to turn on the flash LED, and then set it to AUTO when you want the torch light to turn off.
Also, check out this SO question Camera.Parameters.FLASH_MODE_TORCH replacement for Android 2.1 as it'll tell you about some issues people have run into with certain devices.
Then, for the timer, you can use an instance of Timer and a subclass of TimerTask to do the trick. Here's an example from code I've written to make sure an Internet query isn't taking too long:
private QueryLyricsTask clt;
private Timer t1;
...
/* Make sure the query doesn't take too long */
try {
t1 = new Timer("monitorTimeout");
t1.schedule(new qlt(), lyricsTimeout * 1000);
} catch (Exception e) {
e.printStackTrace();
}
...
class qlt extends java.util.TimerTask {
#Override
public void run() {
if (clt.getStatus() != Status.FINISHED)
clt.cancel(true);
}
}
To explain these variables, "monitorTimeout" is a tag name to reference the Timer by. "qlt" is the class that runs once Timer t1 has elapsed. "lyricsTimeout" is a numeric value specified by the user in the settings (for timeout in seconds). "clt" is an instance of a class derived from AsyncTask so it will run the query without freezing up my UI. Obviously in your case, you probably wouldn't need an AsyncTask, but perhaps a simple "if" statement in run() to toggle the flash torch based on its current state.
Check out the documentation on the Timer class so you can learn how to make Timers that fire once or multiple times, or at certain times of day.
Related
I am trying to make an android app that captures photos after every 5 seconds. Currently the technique i'm using, uses the phone's camera app to capture the photo. It requires the user to capture the photo and then to press ok and only after that the control returns back to the android app. I found some codes to do the same without human interaction, but since i'm new to android, i'm not able to understand codes them because most of them are incomplete and divided into multiple activities. Can this be done using just one activity?
EDIT :
The codes mentioned above can be found here
I suggest to you to use this library (here documentation) instead the official Camera Api of Android that could be really tricky to use for beginners
Then your code could be like this
private final Handler handler = new Handler(); //This should be declared before OnCreate
private Runnable photoRunnable; //This also
CameraView camera = findViewById(R.id.camera);
camera.addCameraListener(new CameraListener() {
public void onPictureTaken(PictureResult result) {
//Handle result here!
}
});
photoRunnable = new Runnable() {
#Override
public void run() {
try {
camera.takePicture(); //The result will be in onPictureTaken
}
catch (Exception e) {
e.printStackTrace();
//Handle Exception!
}
finally{
//also call the same runnable to call it at regular interval
handler.postDelayed(this, 10*1000); //10*1000 is your interval (in this case 10 seconds)
}
}
};
//runnable must be execute once
handler.post(photoRunnable);
Remember to manage the lifecycle of handler
currently trying to create the front-end for my Convolutional neural network image classifier.
what i'm trying to build is an app which sends a continuous stream of images to my server for classification, the total stream classification will be averaged and viewed for the user.
the reason i want this specific trait is because classifying many images of the same 3D object could improve accuracy.
building the app on camera2 demo from github, i wasn't able to google a solution.
i have tried creating a Asynctask which will rerun the takePhoto() method at onPostExecute but canceling the task is close to impossible, without talking about rerunning the task which doesnt allow me to cancel because i'm not saving the task as a variable.
also, each time i take a picture the device stutters a bit, is this unavoidable using camera2?
i have thought about moving to the older camera api, camera2 is a complete pain in the a**.
any new idea would be lovely at this point.
would apreciate if anyone who was able to stream images easily using camera2 or the older ap could post an example or help me with the issue.
this is my asynctask if this actualy could work and im just doing it wrong:
public class AsyncTakePicture extends AsyncTask<Void, Void, Void> {
private boolean running = true;
#Override
protected void onCancelled() {
running = false;
}
#Override
protected Void doInBackground(Void... params) {
while (running) {
takePicture();
try {
// no need for alot of images, so one image per 2 seconds is good
Thread.sleep(2000);
} catch (Exception e) {
running = false;
}
}
return null;
}
protected void onPostExecute(Void result) {
if (running){
myAsyncTask.execute();
} else {
Log.i("AsyncTask:"," done");
}
}
}
the idea is that once the task is called, it will rerun and take more photos until cancelled. Async is called because i don't want the UI to lag. thing is, to repeat the task i cannot initiate it as a variable, and if i cannot initiate then i cannot use cancel(boolean).
I'm writing an APP for taking multiple pictures by camera. (Like the burst mode in Camera2, but I'm working on older versions.)
It is implemented by takePicture() / onPictureTaken() callback, and work normally on several devices except some performance issues. However I got a RuntimeException of startPreview failed on an HTC Sensation device when trying to start preview for the 2nd picture.
Here is the functions about multiple shot:
final int multishot_count = 3;
....
public void TakePicture()
{
// Invoke multishot from UI when the camera preview is already started.
// startup of multishot task
...
m_take_picture_count = 0;
TakeOnePicture();
}
private void TakeOnePicture()
{
m_camera.takePicture(null, null, new Camera.PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, final Camera camera)
{
m_take_picture_count++;
// feed the JPEG data to a queue and handle it in another thread
synchronized(m_jpeg_data_lock)
{
int data_size = data.length;
ByteBuffer buffer = ByteBuffer.allocateDirect(data_size);
buffer.put(data, 0, data_size);
m_jpeg_data_queue.offer(buffer);
if (m_take_picture_count == multishot_count)
m_is_all_pictures_taken = true;
}
if (m_take_picture_count < multishot_count)
{
m_camera.startPreview();
TakeOnePicture();
}
else
{
// Finalize the multishot task and process the image data
EndTakePictureTask end_take_picture_task = new EndTakePictureTask();
end_take_picture_task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
});
}
After the first picture being taken, the startPreview() function may fail in a rate of 10-20% on the specified device. My APP is always run in foreground and has a visible view to show the preview frames. I also try to bypass the JPEG data without processing it, but the error still occurs.
I found a similar report at here. It seems that the underlying thread for taking picture does not finish its works, but we have no way to check it. So I try to catch the exception from startPreview() and sleep a while:
if (m_take_picture_count < multishot_count)
{
boolean is_try_start_preview = true;
while (is_try_start_preview)
{
try
{
m_camera.startPreview();
is_try_start_preview = false;
}
catch (RuntimeException e)
{
try
{
Thread.sleep(50);
}
catch (InterruptedException e2)
{
e2.printStackTrace();
}
}
}
TakeOnePicture();
}
But once startPreview fails, it will fail forever no matter how many times I sleep.
I also found that you need to call setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) for the surface holder in older Android versions to let startPreview() work correctly. But the device has Android version 4.0.3 and should not require this call. I still try to add it but the issue remains the same. Moreover, the first call of startPreview() works correctly while the second call after onPictureTaken() gets the error. This is different from the issue of missing setType() in older versions.
Finally I use an workaround that may greatly hurt the performance:
if (m_take_picture_count < multishot_count)
{
try
{
m_camera.startPreview();
}
catch (RuntimeException e)
{
// Fail to start preview. Workaround: reopen camera.
RestartCamera();
}
TakeOnePicture();
}
That is, when startPreview() fails, I just close the camera, reopen it with the same settings, then start the preview to take another picture.
I want to know if I miss something about the take picture APIs, and is there a solution better than this brute-force workaround.
Thanks for the suggestion from Alex Cohn, I found a solution. This solution is only tested on the HTC Sensation device, but it has dramatic effect on this device.
I just put a sleep instruction before startPreview() that would be called in onPictureTaken():
try
{
Thread.sleep(20);
}
catch (Exception e)
{
e.printStackTrace();
}
Then I run a test 100 times, where each run takes 3 pictures in succession. With the sleep, I didn't get any error from startPreview() in 100 runs. If There is no sleep, I need to reopen the camera 78 times, and restart the device 8 times in 100 runs.
I made a simple application with 2 buttons to test flashlights.
button1.setOnClickListener...etc
if (cameraObj ==null){ return; }
Camera.Parameters cameraParams =cameraObj.getParameters();
if(cameraParams.getFlashMode() == null) { return;}
cameraParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
cameraObj.setParameters(cameraParams);
cameraObj.startPreview();
button2.setOnClick etc...
if(cameraObj==null){ return; }
Camera.Parameters cameraParams = cameraObj.getParameters();
cameraParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
cameraObj.setParameters(cameraParams);
cameraObj.stopPreview();
The application was tested on 2 devices: HTC ONE and HTC DESIRE 500
The application works good on both. The problem is: there's a delay on turning on/off the flashlight.
When I press on and off very fast, the flashlight on DESIRE 500 its turning off and on as I press the buttons, but on HTC ONE there is a delay (it looks like you are not allowed to switch that fast the flashlights). What could be the problem?
You can solve this by adding a fixed delay using Hander which will trigger the flash after a delay,
// variable to fix the timeout duration in milliseconds
// 1000 milliseconds = 1 second
double TIME_OUT = 2*1000;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// time has been reached, turn the flash on
if (cameraObj ==null){ return; }
Camera.Parameters cameraParams =cameraObj.getParameters();
if(cameraParams.getFlashMode() == null) { return;}
cameraParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
cameraObj.setParameters(cameraParams);
cameraObj.startPreview();
}
}
}, TIME_OUT);
So, I have one problem, which I can't solve. My app used over 45% of cpu samsung SII. I think the main reason is postDelayed.
Here is part of my code:
Handler a=new Handler();
a.post(new Runnable(){
#Override
public void run() {
Calendar cal = Calendar.getInstance(Locale.US);
cal.setTime(curr);
Format formatter = new SimpleDateFormat("\r EE \n d");
int currentDOW = cal.get(Calendar.DAY_OF_WEEK);
cal.add(Calendar.DAY_OF_YEAR,(currentDOW*-1)+i+2);
den.setText(formatter.format(cal.getTime()));
}
a.postDelayed(this,400);
});
So, this is part of my code, it is work, but I think, it is the main reason of high CPU usage. Please help me! Thank you!
you could optimize the code a bit , but i suspect that you simply don't stop the updating when you don't need to , so more and more updates are being accumulated .
as an example , if you change the orientation , it will add more events of the previous activitiy (which was destroyed) and you end up with double the rate of updating .
I had this problem. My app was using around 60% CPU time until I added the following code to my run() method in my worker thread:
#Override
public void run()
{
while( _running )
{
// do usual stuff
// ...
// ** add the following to the end of your loop **
try
{
Thread.sleep( 5 );
}
catch( InterruptedException e )
{
_running = false;
/* at least we tried */
}
}
}
It now uses ~8% CPU with no noticeable difference.
Experiment with the value '5'. I've added an app setting to allow the user to balance better graphics (i.e. number lower than 5) with better battery usage (number higher than 5).