Android - Camera flash light blinking in wrong intervals in different devices - android

I am developing an app, in which I want to blink the flash light in specific interval.
Below are the steps I have followed.
1) Set the Timer for specific interval.
2) In run() method i did the code for TurnOn and TurnOff flash.
But the interval of flash blinking is different on different devices. The timer time is same for all devices, I have also put a Log in between, I am getting same values but, still the problem is there.
Is it a Hardware issue, because the hardware is different for different devices. I have also tested in iPhone 5s (By converting same code in iOS) but, the flash blinking is much faster than Android.
For Android, I have tested on Nexus 4, Motorola G2, Sony Xperia Neo and it is working fine.
Problem is with Nexus 5 and Samsung Galaxy S4.
EDIT
Code of Timer :
long delayLong = 200;
long timerValueLong = 500;
Timer timer;
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if (!mLightOn) {
turnOnFlash();
} else {
turnOffFlash();
}
}
}, delayLong, timerValueLong);

This is an older problem, but the problem still persists today so I'll post how I solved this.
The problem is that the call to turn the LED on or off takes variable amount of time to traverse through the Android operating system. The way these calls are handled are phone dependent.
First off you need to measure the time it takes for the LED to turn on and off starting from the time the call to do so. Use the input from the camera, keep the phone close to a surface and measure the change in brightness in the frame. You can use glReadPixels if working with OpenGL and read out the center line only each frame. You will need to make multiple measurements, as the call can be shorter or longer depending on the state of the OS. Preferably you'd want to have no buffer or a fixed buffer of frames, so timing of the frames is reliable (which might not be the case with compression). I used OpenGL and a SurfaceTexture and this is a snappy way.
You now know the minimum(1) and maximum(2) time it takes for the call to traverse the OS. Using this information you can make the LED blink as fast as possible on the phone. To truly get the most out of it, start the second call to the flash before maximum(2) time has passed; maximum(2) - minium(1).
Using the last trick, the speed of the flashing is mostly dependent on the difference in minimum and maximum time of the call traversal. This is typically very different per phone, from 10ms to 100ms+.
Also note that because the measuring of the call traversal time happens with the camera, times are rounded up/down to 33ms segments (#30fps).

I had the same issue with the flashlight and the problem is not related to the Timer. It is about how you are turning the flash on and off. On some devices like Nexus 5, you have to have and use a SurfaceView inside of your layout. It would be useful to show us the methods you are using for turning the flashlight on and off.

long delayLong = 20;
long timerValueLong = 100;
Timer timer;
final Parameters p = camera.getParameters();
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if (!isLighOn) {
p.setFlashMode(Parameters.FLASH_MODE_ON);
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
isLighOn = true;
} else {
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
isLighOn = false;
}
}
}, delayLong, timerValueLong);

Maybe you can try to use Alarm functions like:
https://developer.android.com/training/scheduling/alarms.html
https://developer.android.com/reference/android/provider/AlarmClock.html
your can set repeat period for alarm. make 2 alarms, one for On and one for Off.
Even phone has hard working, alarm will work depending on clock time. so maybe it will not Off and twice On by error, but solution will be same.
and also you are using 200 milliseconds. it's hard for device catch such small time interval. maybe you'll try to increase you time intervals?

Related

How to avoid sluggish d3 force layout on Android?

We're using a d3.layout.force on a web app, and I've been investigating a bug report that it is sluggish on Android: it feels like the nodes are in oil, compared to how it works on desktop browsers, or iOS.
(By the way, we only ever have between 4 and 9 nodes, and the sluggishness does not feel different between 4 and 9.)
We set size(), linkDistance() and charge(); so we're using the defaults for friction, theta, alpha, gravity, etc. I experimented with these to try and reproduce the effect on desktop, but couldn't. (friction(0.67), instead of default of 0.9, was closest, but still felt different, somehow.)
I then set up an FPS meter (based on calls to the tick() function). We get 60fps on desktop, and it seems in the 40s and 50s on an ipad. But on Android Chrome (on a Nexus 7) it seems capped at 30fps, and is often half that. Android Firefox was in the 20s normally, but sometimes into the 30s.
So, is it a reasonable hypothesis that are Android devices are just slower? Could there be a cap of 30fps in Android Chrome?
Then how can I fix this? I believe d3.js uses requestAnimationFrame(). Often animation libraries take the time between calls to requestAnimationFrame() to decide how far to move objects (so when the CPU gets overloaded the animation becomes jerkier, but takes the same amount of time to complete). But it appears that d3.js does not do this, and moves everything the same amount by tick, not by elapsed time. What can I do about this?
(Ideally I'd like a solution based on how slow/fast the machine is, rather than having to sniff the browser.)
Curiously, adding more calls to force.tick() in my own requestAnimationFrame() handler (see https://stackoverflow.com/a/26189110/841830), does increase the FPS. That suggests it is not CPU bound, but instead a limit that Android is enforcing (perhaps to save battery?).
Here is the code I'm using, that tries to adapt dynamically to the current fps; it ain't beautiful but seems to be getting the job done in my test android devices, without changing the behaviour in iOS or desktop.
First, where you set up the force layout:
var ticksPerRender = 0;
var animStartTime,animFrameCount;
force.on('start',function start(){
animStartTime = new Date();animFrameCount=0;
});
requestAnimationFrame(function render() {
for(var i = 0;i < ticksPerRender;i++)force.tick();
if(force.alpha() > 0)requestAnimationFrame(render);
});
The above does two things:
sets up the fps counter
sets up our own animation callback, which does nothing by default (ticksPerRender starts off as zero).
Then at the end of your tick handler:
++animFrameCount;
if(animFrameCount>=15){ //Wait for 15, to get an accurate count
var now = new Date();
var fps = (animFrameCount / (now - animStartTime))*1000;
if(fps < 30){
ticksPerRender++;
animStartTime = now;animFrameCount = 0; //Reset the fps counter
}
if(fps > 60 && ticksPerRender >= 1){
ticksPerRender--;
animStartTime = now;animFrameCount = 0; //Reset the fps counter
}
}
This says that if the FPS is low (below 30), do an extra call to tick() on each animation frame. And if it goes high (over 60), remove that extra call.
Each time ticksPerRender is changed, we measure the FPS from scratch.

android sony smartwatch 2 control led not working

I'm developing Sony smart watch extension and need to control over led. I have implemented active low power mode so watch back light can never go off. SO far its working good. But now i need to light the led when new data come from mobile app to watch. I am able to have that data in watch but at the same time i want to light the back light ON. I searched on official documentation and come to know about CONTROl_LED_INTENT in this link
I am calling this snippet at the time of data insertion
Intent intent = new Intent(Control.Intents. CONTROL_LED_INTENT);
intent.putExtra(Control.Intents.EXTRA_ON_DURATION, 20);
intent.putExtra(Control.Intents.EXTRA_OFF_DURATION, 50);
intent.putExtra(Control.Intents.EXTRA_REPEATS, 2);
intent.putExtra(Control.Intents.EXTRA_LED_COLOR, 1);
sendToHostApp(intent);
but not able to turn light on. How can i make light on.
You can set the screen state to SCREEN_STATE_AUTO or SCREEN_STATE_ON as per the API References which effectively switches on the backlight of the screen.
https://developer.sony.com/reference/sony-addon-sdk/com/sonyericsson/extras/liveware/extension/util/control/ControlExtension#setScreenState(int)
An example of a snippet with this
Intent intent = new Intent(Control.Intents.CONTROL_SET_SCREEN_STATE_INTENT);
intent.putExtra(Control.Intents.EXTRA_SCREEN_STATE, Control.Intents.SCREEN_STATE_AUTO);
sendToHostApp(intent);
Try a longer value. 20 milliseconds is 2 hundredths of a second. You may not be able to see it or the hardware may not be able to do that.

Slow SeekBar performance on Android

I'm trying to hook up a basic audio player. The audio side is done, but I'm using a SeekBar as a track scrubber and I'm having trouble with performance.
The SeekBar is from an XML layout, and I'm using fairly basic code to update it:
updateTask = new Runnable() {
public void run() {
int elapsed = 0;
if (player != null) {
elapsed = player.getElapsedTime(); // Seconds
}
trackSeekbar.setProgress(elapsed);
updateHandler.postDelayed(this, 1000);
}
};
updateHandler.postDelayed(updateTask, 1000);
This code is taking between 20%–50% CPU on a Nexus 10! It makes other parts of my app are very choppy so it has to be faster.
I have already taken out some things in the layout to try and reduce layout redraws (I was displaying the elapsed time in a text box but gave up because it was just too slow), but I do need a basic scrubber. When I take out the call to setProgress() CPU drops to 1%. Is there a better way of doing this?
The cause of the poor performance was a high resolution transparent PNG in the background. When I removed it, all the various performance issues disappeared.
On the Nexus 10, the image was 2560x1440 which is its native resolution. Seemingly Android is not able to cope with full resolution background images.

Android: How to find the frame rate of a device?

Frame rate: I'm referring to the rate at which display changes. i.e. Ondraw() is called and the canvas is redrawn.
Is there a default rate for all android devices ? As this rate depends on the processing power of the device , How to find out the frame rate of a device , before starting to program for that mobile device ?
This may be a follow-up to this question, where I suggested that having a redraw loop that just kept drawing over and over again might be a bit excessive. There may be an api to find out the capabilities of the devices display, but if there is I'm not aware of it. When you're writing your own event loop / thread function you can control the framerate by how often you call your 'draw' method. Typically, I think for most purposes, you would be ok with a refresh rate of 30 or so. If you're writing a fast action game, that needs rapid animation then you may want to run as fast as you can, the more fps, the smoother it will be.
A typical event loop (thread run function) might look something like this:
// define the target fps
private static final int UPDATE_RATE = 30; // Frames per second (fps)
public void run() {
while(running) { // volatile flag, set somewhere else to shutdown
long beginTimeMillis, timeTakenMillis, timeLeftMillis;
// get the time before updates/draw
beginTimeMillis = System.currentTimeMillis();
// do the thread processing / draw
performUpdates(); // move things if required
draw(); // draw them on the screen
// get the time after processing and calculate the difference
timeTakenMillis = System.currentTimeMillis() - beginTimeMillis;
// check how long there is until we reach the desired refresh rate
timeLeftMillis = (1000L / UPDATE_RATE) - timeTakenMillis;
// set some kind of minimum to prevent spinning
if (timeLeftMillis < 5) {
timeLeftMillis = 5; // Set a minimum
}
// sleep until the end of the current frame
try {
TimeUnit.MILLISECONDS.sleep(timeLeftMillis);
} catch (InterruptedException ie) {
}
}
}
You can use the dumpsys tool provided by Android. To obtain information about the display of the device execute the command:
adb shell dumpsys display
The information about the frame rate of the device is provided in the attribute "mPhys".
You will find something like:
mPhys=PhysicalDisplayInfo{1080x1920, 60.000004 fps, densitiy 3.0,
480.0x480.0 dpi, secure true}
The frame rate of the device is in the second field, in my case is 60.000004 fps
You can't rely on a certain framerate. Android is a using multitasking operating system. If there are some threads running in the background that do some heavy lifting, you might not be able to reach the framerate you want. Even if you're the only active process, the framerate depends on your GPU and CPU, and the clock of each. Maybe the user has a hacked ROM that changes the clock to a custom value.
Some phones might be locked to a certain framerate. The HTC EVO was locked to 30fps for the longest time, until custom ROMs came out that removed that limitation. Newer EVO ROMs also removed that limitation.
I don't know what you're trying to do, but your best bet is to measure the time after each frame and use that delta for your animations. If you're trying to display the FPS, then use a smoothed average.
There is a simple tricky way to find device FPS during runtime.
Just call the following method:
long oneSecondLater=0;
int FPS=0;
int counter=0;
ValueAnimator v_animator;
private void logFPS()
{
oneSecondLater = System.currentTimeMillis()+1000;
v_animator = ValueAnimator.ofFloat(0.0f, 1.0f);
v_animator.setRepeatCount(ValueAnimator.INFINITE);
v_animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
FPS++;
if(System.currentTimeMillis() > oneSecondLater)
{
counter++;
if(counter>1)//ignore the first onAnimationUpdate call (it is not correct)
Log.i("checkFPS","FPS:" + FPS);
FPS=0;
oneSecondLater = System.currentTimeMillis()+1000;
}
}
});
v_animator.start();
}
I log FPS every second, The output of my Logcat was as follows
It works because for ValueAnimator, onAnimationUpdate() method will call according to device FPS;
This might be an old question, but for future reference, I found this library named Takt
https://github.com/wasabeef/Takt.
Takt is Android library for measuring the FPS using Choreographer.

How to simulate speed on Android emulator?

Is there a way to simulate speed on Android emulator?
[edit]
The purpose of this to test the getSpeed() method
Example:
I would like to set the device is going at 20 miles an hour.
Yes you can do that. If your using Eclipse to develop your app, you have to go to the DDMS perspective. There you should find a window called Emulator control. In this window you can send new geo locations (GPS coordinates) to your emulator or device. As you want to emaulte speed its better to use GPX or KML files. In this files you can define GPS coordinates and these coordinates are then read step by step. By choosing this coordinates appropriately you can simluate a constant speed.
The Location object has a method to set the speed of the device:
//the instance
Location location;
//retrieves the speed of the device
location.getSpeed()
// set the speed of the device of course for testing purporses, remember to
// remove this when deploying your appplication
location.setSpeed((float) 20.0)
If you want to simulate a change of speed over a time you can set a timer and decrease or increase the speed in that span of time, for example:
int secondsDelayed = 5;
new Handler().postDelayed(new Runnable() {
public void run() {
location.setSpeed((float) 50.0);
}
}, secondsDelayed * 1000);
This will incrase the speed to 50 km/p over a span of 5 seconds
I've faced the same problem with my high config pc have 3i 4GB , but the emulator works so slow
I found something that worked for me and hope it may work for others i would love to share it here
i've just added Device ram size to My existing AVD and set the size to 1000MB(Because i've enough to allot mind 4GB)
No the speed of my AVD was ultimate hope it may help you.

Categories

Resources