For loop not acting as expected - android

Good night.
I have a for loop to calculate some values along the week, during some weeks. My code compare day of the week with the quantity of days that have passed.
The for only works fine on monday when workday is the same than totdays. The rest of days totact is 0 and the fianl equation become NaN.
int totdias = PrefProteos.getInt("dia",0);
int totact = 0;
float califtot = 0;
int stateday = 0;
float promdias;
float promcalif;
int workdays;
Date day = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("EE", Locale.US);
String dayweek = formatter.format(day);
if (dayweek.equals("Mon")) {
stateday = 1;
}
else if (dayweek.equals("Tue")) {
stateday = 2;
}
else if (dayweek.equals("Wed")) {
stateday = 3;
}
else if (dayweek.equals("Thu")) {
stateday = 4;
}
else if (dayweek.equals("Fri")) {
stateday = 5;
}
else if (dayweek.equals("Sat")) {
stateday = 6;
}
else if (dayweek.equals("Sun")) {
stateday = 7;
}
if (stateday >= totdias) {
workdays = 1;
promdias = totdias;
} else {
workdays = (totdias - (stateday - 1));
promdias = stateday;
}
for (int y = workdays; y == totdias;y++) {
for (int x = 1; x <= 12; x++) {
String activ=PrefProteos.getString("act" + x + "-habit", "");
if (!activ.equals("")) {
float notactiv = PrefProteos.getFloat("act" + x + "-puntdia"+y, 0);
califtot = califtot+notactiv;
totact = totact+1;
}
}
}
promcalif = califtot / (totact * promdias);

You have write your first loop condition wrong, you ask only for to run only if workdays = totdias. I guess you want to loop for each days from workdays to totdias
So correct this block :
for (int y = workdays; y == totdias;y++) {
Into
for (int y = workdays; y <= totdias;y++) {
PS :
Your current loop is like writing
if(workdays == totdias) {

You should provide some more code because we can't understand your PrefProteos class and probably the error is in there.
You should also add the full logcat
And you should tell us which line throws the error.
Anyway there are some errors:
Here
for (int y = workdays;y==totdias;y++){
There is no sense of using an equals condition in a for loop exit condition if both equals condition and looping variable are the same, because it will result in an if loop. This is because the for will work only if workdays == totdias since the beginning, elseway it will not work.
For conditions are:
for(counter = defaultvalue; condition that if true, makes the loop goes on; what to do each loop end)
This means that your code will do:
is y(workdays) == totdias?
if yes, do the loop
add one to y(workdays)
exit because the condition is no more true
if not, don't run the loop
So you simply have to call:
if(y == totdias){
//do code
y++;
}
But probably this is an error, because except for monday, this code will never run! so in others days promdias is not istantiated
In the loop
for (int x = 1; x<=12; x++){
String activ=PrefProteos.getString("act" + x + "-habit", "");
if (!activ.equals("")){
//there must be an error here somewhere
float notactiv=PrefProteos.getFloat("act" + x + "-puntdia"+y, 0);
califtot=califtot+notactiv;
totact=totact+1;
}
}
And this must be throwing an error.
promcalif = califtot/(totact*promdias);
Two options:
promidias or totact are 0. you can't do number/0
As said above, promdias might not be istantiated in other days of the week, because the for loop never run
Btw, float name = 0; is not perfect, change them to float name = 0f;

Related

I want to generate random number in android but exclude some that end with zero

int min = 651;
int max = 999;
Random r = new Random();
do {
final int i1 = r.nextInt(max - min + 1) + min;
}
while(i1 %10 == 0);
I want to generat random number in this(651 to 999) range but don't want 660,670,680 so on which ends with zero or in middle(707,805) so help me in this case
in this code error:- i1 in while loop is not local variable
You can do as follows. All you have to do is, loop until you find a number that is not divisible by 10.
int min = 651;
int max = 999;
Random r = new Random();
int randomNum;
while(true){
randomNum = rand.nextInt((max - min) + 1) + min;
if(randomNum%10!=0){
break;
}
}
//now you have the required random number
What's wrong in your code
What you had done was right, apart from accessing a local variable outside of its context. You have to declare i1 outside of the while loop's context. Also, remember, a final int cannot be modified once assigned. In your case this doesn't affect since it is in the context of the while loop.
int i1; //this should come here.
do {
i1 = r.nextInt(max - min + 1) + min; // no final anymore
}
while(i1 %10 == 0);

It seems that Paint.measureText() function is not correct for all languages

I have implemented ellipsize text function that works perfectly correct for English Strings. When applied to some languages as Deutch however strings are not truncated properly. After debuugging I came to conclusion that measureText is not workning properly. Here is my code:
for (int i = 0; i < valueCount; i++) {
textWidth = mSelectorWheelPaint.measureText(mOriginalValues[i]);
if (textWidth > maxStringWidth) {
float diff = textWidth - maxStringWidth;
int numlettersToSubstract = Math.round(diff / oneLetterWidth);
int length = mOriginalValues[i].length();
mDisplayedValues[i] = mOriginalValues[i].substring(0,
(length - 1) - (numlettersToSubstract + 3));
if (!CustomLocaleUtil.isRTL()) {
mDisplayedValues[i] = String.format("%s...",
mDisplayedValues[i]);
} else {
mDisplayedValues[i] = String.format("...%s",
mDisplayedValues[i]);
}
} else {
mDisplayedValues[i] = mOriginalValues[i];
}

counter in the loop, after finish start again

I need a counter that when it reaches the maximum value, starts to count from the beginning. I tried some if statements, but i am new in android developing and my attempts was wrong. Please help me a little. Thank you
Example:
int maxValue = 10;
for (int i = 0; i <= maxValue; i++)
{
if ( i == maxValue)
{
i = 0;
}
}

how to calculate exact foot step count using accelerometer in android?

I am developing some application like Runtastic Pedometer using the algorithm but I am not getting any similarity between the results.
my code is as follows:
public void onSensorChanged(SensorEvent event)
{
Sensor sensor = event.sensor;
synchronized (this)
{
if (sensor.getType() == Sensor.TYPE_ORIENTATION) {}
else {
int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0;
if (j == 1) {
float vSum = 0;
for (int i=0 ; i<3 ; i++) {
final float v = mYOffset + event.values[i] * mScale[j];
vSum += v;
}
int k = 0;
float v = vSum / 3;
//Log.e("data", "data"+v);
float direction = (v > mLastValues[k] ? 1 : (v < mLastValues[k] ? -1 : 0));
if (direction == - mLastDirections[k]) {
// Direction changed
int extType = (direction > 0 ? 0 : 1); // minumum or maximum?
mLastExtremes[extType][k] = mLastValues[k];
float diff = Math.abs(mLastExtremes[extType][k] - mLastExtremes[1 - extType][k]);
if (diff > mLimit) {
boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k]*2/3);
boolean isPreviousLargeEnough = mLastDiff[k] > (diff/3);
boolean isNotContra = (mLastMatch != 1 - extType);
if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) {
for (StepListener stepListener : mStepListeners) {
stepListener.onStep();
}
mLastMatch = extType;
}
else {
Log.i(TAG, "no step");
mLastMatch = -1;
}
}
mLastDiff[k] = diff;
}
mLastDirections[k] = direction;
mLastValues[k] = v;
}
}
}
}
for registering sensors:
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(mStepDetector,mSensor,SensorManager.SENSOR_DELAY_NORMAL);
in the algorithm i have different levels for sensitivity as public void
setSensitivity(float sensitivity) {
mLimit = sensitivity; // 1.97 2.96 4.44 6.66 10.00 15.00 22.50 33.75 50.62
}
on various sensitivity level my result is:
sensitivity rantastic pedometer my app
10.00 3870 5500
11.00 3000 4000
11.15 3765 4576
13.00 2000 890
11.30 754 986
I am not getting any proper pattern to match with the requirement.
As per my analysis this application is using Sensor.TYPE_MAGNETIC_FIELD for steps calculation please let me know some algorithm so that I can meet with the requirement.
The first thing you need to do is decide on an algorithm. As far as I know there are roughly speaking three ways to detect steps using accelerometers that are described in the literature:
Use the Pythagorean theorem to calculate the magnitude of the acceleration vector of each sample from the accelerometer. Low-pass filter the magnitude signal to remove high frequency noise and then look for peaks and valleys in the filtered signal. You may need to add additional requirements to remove false positives. This is by far the simplest way to detect steps, it is also the way that most if not all ordinary pedometers of the sort that you can buy from a sports store work.
Use Pythagoras' like in (1), then run the signal through an FFT and compare the output from the FFT to known outputs of walking. This requires you to have access to a fairly large amount of training data.
Feed the accelerometer data into an algorithm that uses some suitable machine learning technique, for example a neural network or a digital wavelet transform. You can of course include other sensors in this approach. This also requires you to have access to a fairly large amount of training data.
Once you have decided on an algorithm you will probably want to use something like Matlab or SciPy to test your algorithm on your computer using recordings that you have made on Android phones. Dump accelerometer data to a cvs file on your phone, make a record of how many steps the file represents, copy the file to your computer and run your algorithm on the data to see if it gets the step count right. That way you can detect problems with the algorithm and correct them.
If this sounds difficult, then the best way to get access to good step detection is probably to wait until more phones come with the built-in step counter that KitKat enables.
https://github.com/bagilevi/android-pedometer
i hope this might be helpfull
I am using step detection in my walking instrument.
I get nice results of step detection.
I use achartengine to plot accelerometer data.
Take a look here.
What I do:
Analysis of magnitude vector for accelerometer sensor.
Setting a changeable threshold level. When signal from accelerometer is above it I count it as a step.
Setting the time of inactive state (for step detection) after first crossing of the threshold.
Point 3. is calculated:
arbitrary setting the maximum tempo of our walking (e.g. 120bpm)
if 60bpm - 1000msec per step, then 120bpm - 500msec per step
accelerometer passes data with certain desired frequency (SENSOR_DELAY_NORMAL, SENSOR_DELAY_GAME, etc.). When DELAY_GAME: T ~= 20ms (this is included in Android documentation)
n - samples to omit (after passing the threshold)
n = 500msec / T
n = 500 / 20 = 25 (plenty of them. You can adjust this value).
after that, the threshold becomes active.
Take a look at this picture:
This is my realization. It was written about 1.5-2 years ago. And I really don't remember all this stuff that I wrote. But it worked. And it worked good for my needs.
I know that this is really big class (some methods are deleted), but may be it will be helpful. If not, I'll just remove this answer...
public class StepDetector implements SensorEventListener
{
public static final int MAX_BUFFER_SIZE = 5;
private static final int Y_DATA_COUNT = 4;
private static final double MIN_GRAVITY = 2;
private static final double MAX_GRAVITY = 1200;
public void onSensorChanged(final SensorEvent sensorEvent)
{
final float[] values = sensorEvent.values;
final Sensor sensor = sensorEvent.sensor;
if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
{
magneticDetector(values, sensorEvent.timestamp / (500 * 10 ^ 6l));
}
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
accelDetector(values, sensorEvent.timestamp / (500 * 10 ^ 6l));
}
}
private ArrayList<float[]> mAccelDataBuffer = new ArrayList<float[]>();
private ArrayList<Long> mMagneticFireData = new ArrayList<Long>();
private Long mLastStepTime = null;
private ArrayList<Pair> mAccelFireData = new ArrayList<Pair>();
private void accelDetector(float[] detectedValues, long timeStamp)
{
float[] currentValues = new float[3];
for (int i = 0; i < currentValues.length; ++i)
{
currentValues[i] = detectedValues[i];
}
mAccelDataBuffer.add(currentValues);
if (mAccelDataBuffer.size() > StepDetector.MAX_BUFFER_SIZE)
{
double avgGravity = 0;
for (float[] values : mAccelDataBuffer)
{
avgGravity += Math.abs(Math.sqrt(
values[0] * values[0] + values[1] * values[1] + values[2] * values[2]) - SensorManager.STANDARD_GRAVITY);
}
avgGravity /= mAccelDataBuffer.size();
if (avgGravity >= MIN_GRAVITY && avgGravity < MAX_GRAVITY)
{
mAccelFireData.add(new Pair(timeStamp, true));
}
else
{
mAccelFireData.add(new Pair(timeStamp, false));
}
if (mAccelFireData.size() >= Y_DATA_COUNT)
{
checkData(mAccelFireData, timeStamp);
mAccelFireData.remove(0);
}
mAccelDataBuffer.clear();
}
}
private void checkData(ArrayList<Pair> accelFireData, long timeStamp)
{
boolean stepAlreadyDetected = false;
Iterator<Pair> iterator = accelFireData.iterator();
while (iterator.hasNext() && !stepAlreadyDetected)
{
stepAlreadyDetected = iterator.next().first.equals(mLastStepTime);
}
if (!stepAlreadyDetected)
{
int firstPosition = Collections.binarySearch(mMagneticFireData, accelFireData.get(0).first);
int secondPosition = Collections
.binarySearch(mMagneticFireData, accelFireData.get(accelFireData.size() - 1).first - 1);
if (firstPosition > 0 || secondPosition > 0 || firstPosition != secondPosition)
{
if (firstPosition < 0)
{
firstPosition = -firstPosition - 1;
}
if (firstPosition < mMagneticFireData.size() && firstPosition > 0)
{
mMagneticFireData = new ArrayList<Long>(
mMagneticFireData.subList(firstPosition - 1, mMagneticFireData.size()));
}
iterator = accelFireData.iterator();
while (iterator.hasNext())
{
if (iterator.next().second)
{
mLastStepTime = timeStamp;
accelFireData.remove(accelFireData.size() - 1);
accelFireData.add(new Pair(timeStamp, false));
onStep();
break;
}
}
}
}
}
private float mLastDirections;
private float mLastValues;
private float mLastExtremes[] = new float[2];
private Integer mLastType;
private ArrayList<Float> mMagneticDataBuffer = new ArrayList<Float>();
private void magneticDetector(float[] values, long timeStamp)
{
mMagneticDataBuffer.add(values[2]);
if (mMagneticDataBuffer.size() > StepDetector.MAX_BUFFER_SIZE)
{
float avg = 0;
for (int i = 0; i < mMagneticDataBuffer.size(); ++i)
{
avg += mMagneticDataBuffer.get(i);
}
avg /= mMagneticDataBuffer.size();
float direction = (avg > mLastValues ? 1 : (avg < mLastValues ? -1 : 0));
if (direction == -mLastDirections)
{
// Direction changed
int extType = (direction > 0 ? 0 : 1); // minumum or maximum?
mLastExtremes[extType] = mLastValues;
float diff = Math.abs(mLastExtremes[extType] - mLastExtremes[1 - extType]);
if (diff > 8 && (null == mLastType || mLastType != extType))
{
mLastType = extType;
mMagneticFireData.add(timeStamp);
}
}
mLastDirections = direction;
mLastValues = avg;
mMagneticDataBuffer.clear();
}
}
public static class Pair implements Serializable
{
Long first;
boolean second;
public Pair(long first, boolean second)
{
this.first = first;
this.second = second;
}
#Override
public boolean equals(Object o)
{
if (o instanceof Pair)
{
return first.equals(((Pair) o).first);
}
return false;
}
}
}
One main difference I spotted between your implementation and the code in the grepcode project is the way you register the listener.
Your code:
mSensorManager.registerListener(mStepDetector,
mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
Their code:
mSensorManager.registerListener(mStepDetector,
mSensor,
SensorManager.SENSOR_DELAY_FASTEST);
This is a big difference. SENSOR_DELAY_NORMAL is intended for orientation changes, and is therefor not that fast (ever noticed that it takes some time between you rotating the device, and the device actually rotating? That's because this is some functionality that does not need to be super fast (that would probably be pretty annoying even). The rate at which you get updates is not that high).
On the other hand, SENSOR_DELAY_FASTEST is intended for things like pedometers: you want the sensor data as fast and often as possible, so your calculations of steps will be as accurate as possible.
Try to switch to the SENSOR_DELAY_FASTEST rate, and test again! It should make a big difference.
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER ){
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
currentvectorSum = (x*x + y*y + z*z);
if(currentvectorSum < 100 && inStep==false){
inStep = true;
}
if(currentvectorSum > 125 && inStep==true){
inStep = false;
numSteps++;
Log.d("TAG_ACCELEROMETER", "\t" + numSteps);
}
}
}

animate number change

i want to build a component that will be able to show a integer number max 5 digits in the style of the old analog car counters and animate the digit change.
that looks something like this maybe...
i have tried searching for this kinda of examples but i couldn't find anything so far.
in your opinion what is the best approach to achieve this?
i looked at the iphone alarm time picker and as far as i can tell there is only a fixed background and they push the numbers in or out the view. but how do i place the digits in this case and reference them to a particular value?
tnx.
You can try to create your own view, extending view and overriding onDraw().
Here you can use rows of numbers in bitmaps and editing their position based on the number you wish to show.
Dont forget to call invalidate() after setting new numbers to redraw the view.
I will paste an example containing a start for your project.
The bitmap number is a vertical image with numbers from 1-9 (and 0&.)
Ex.
class TickerView extends View { ..
public void setDouble(double d) {
value = d;
invalidate();
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int startx = 0;
int starty = 0;
DecimalFormat df = new DecimalFormat("#0.00");
String str = df.format(value);
String original = Double.toString(value);
Bitmap nums = BitmapFactory.decodeResource(context.getResources(),
R.drawable.numbers);
for (int i = 0; i < str.length(); i++) {
int num = 0;
try {
num = Integer.parseInt(str.charAt(i) + "");
} catch (Exception e) {
num = 10;
}
int numbefore = 0;
try {
numbefore = Integer.parseInt(original.charAt(i -1) + "");
} catch (Exception e) {
numbefore = 0;
}
canvas.drawBitmap(nums, startx + (i * 40), (starty + 40)
- (num * 50) + (numbefore), paintY);
}
paintY.setStrokeWidth(10);
canvas.drawLine(startx, starty+36, startx + (str.length() * 40), starty+36,
paintY);
canvas.drawLine(startx, starty + 90, startx + (str.length() * 40),
starty + 90, paintY);
invalidate();
}
}

Categories

Resources