I'm new to Android programming. Right now, I want to update a TextView value in an Activity at a specified interval.
Car class:
public class Car {
public int Speed;
public int RPM;
public int Distance;
public int Fuel;
public Car(int Speed, int RPM, int Distance, int Fuel) {
System.out.println(
"Inisialisasi Baru"+
"\nSpeed: "+ Speed +
"\nRPM: "+ RPM +
"\nDistance: "+ Distance +
"\nFuel: "+ Fuel
);
this.Speed = Speed;
this.RPM = RPM;
this.Distance = Distance;
this.Fuel = Fuel;
}
public int getSpeed() {
return Speed;
}
public int getRPM() {
return RPM;
}
public int getDistance() {
return Distance;
}
public int getFuel() {
return Fuel;
}
}
Activity java:
TextView carSpeed, carRPM, carDistance, carFuel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mock);
carSpeed = (TextView) findViewById(R.id.carSpeed);
carRPM = (TextView) findViewById(R.id.carRPM);
carDistance = (TextView) findViewById(R.id.carDistance);
carFuel = (TextView) findViewById(R.id.carFuel);
new Timer().scheduleAtFixedRate(new TimerTask(){
Car car = new Car(20, 20, 20, 5);
#Override
public void run(){
int maxSpeed = car.Speed + 5;
int minSpeed = car.Speed - 4;
int maxRPM = car.RPM + 5;
int minRPM = car.RPM - 4;
car.Speed = new Random().nextInt((maxSpeed - minSpeed) + 1) + minSpeed;
car.RPM = new Random().nextInt((maxRPM - minRPM) + 1) + minRPM;
car.Distance += 1;
car.Fuel -= 1;
if (car.Fuel <= 0) {
car.Fuel += 20;
}
if (car.Speed <= 0) {
car.Speed = 20;
} else if (car.Speed >= 150) {
car.Speed -= 50;
}
carSpeed.setText(Integer.toString(car.getSpeed()) + " km/h");
carRPM.setText(Integer.toString(car.getRPM()) + " rpm");
carDistance.setText(Integer.toString(car.getDistance()) + " km");
carFuel.setText(Integer.toString(car.getFuel()) + " l");
}
},0,5000);
}
I think the problem happens because I'm trying to setText inside new Timer() and this cause application close. Thank you.
Yes your intuition is correct. The problem happens because the views are being updated from the timer.
The error will be similar to this:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
In Android, views can only be updated from the "UI thread" also commonly known as the "Main Thread".
The problem here is that the Runnable's run() method is being executed in a separate thread.
The updates can be done on the main thread from an Activity like this:
...
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do all your view updates in here
textView.setText("string");
}
});
....
I cannot see the context of your code, but if it is a fragment:
getActivity().runOnUiThread(...);
There are also other methods for switching to the main thread. You may want to investigate AsyncTask and Handlers as well.
Related
I made an app about android water drinking monitor. But it does the wrong calculation as a percentage. What do you think I might have done wrong.
(When the progress bar is 100 at 100, the daily water calculation is wrong)
waterml = sharedPreferences.getInt(WATER_ML, 0);
waterdata = sharedPreferences.getInt(WATER_DATA, 0);
int dailywater = 2838; // example
ml100.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//scale 100 ml
int percent = 100 * 100 / dailywater;
ProgressBarAnimation anim = new ProgressBarAnimation(circlebar, waterdata, (waterdata + percent));
anim.setDuration(300);
circlebar.startAnimation(anim);
dailywater.setText((waterml + 100) + " / " + dailywater + " ml");
editor = sharedPreferences.edit();
editor.putInt(WATER_DATA, (waterdata + percent));
editor.putInt(WATER_ML, (waterml + 100));
editor.apply();
}
});
////
public static class ProgressBarAnimation extends Animation {
private CircleProgressBar progressBar;
private float from;
private float to;
ProgressBarAnimation(CircleProgressBar progressBar, float from, float to) {
super();
this.progressBar = progressBar;
this.from = from;
this.to = to;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
float value = from + (to - from) * interpolatedTime;
progressBar.setProgress((int) value);
}
}
It seems to me like your code, namely editor.apply(); is working as follows:
you are trying to save the progress and it occurs that sometimes it is called multiple times in a row. According to documentation if you are sending several apply() or commit() commands only the last one will be executed. Therefore, some clicks might not be processed.
I suggest you simply changing your variable for progress and saving it later:
waterml = sharedPreferences.getInt(WATER_ML, 0);
waterdata = sharedPreferences.getInt(WATER_DATA, 0);
int dailywater = 2838; // example
ml100.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//scale 100 ml
int percent = 100 * 100 / dailywater;
ProgressBarAnimation anim = new ProgressBarAnimation(circlebar, waterdata, (waterdata + percent));
anim.setDuration(300);
circlebar.startAnimation(anim);
dailywater.setText((waterml + 100) + " / " + dailywater + " ml");
waterdata += percent;
waterml += 100;
}
});
and then in your onPause() function you simply save them:
public void onPause() {
editor = sharedPreferences.edit();
editor.putInt(WATER_DATA, waterdata);
editor.putInt(WATER_ML, waterml);
editor.apply();
}
If you want your percent not to be rounded, you could change putInt to putFloat and getInt to getFloat
From this thread: How to Customize a Progress Bar In Android
I made my own progress bar using ClipDrawAble animation and it works perfecty, and the code is here:
public class MainActivity extends AppCompatActivity {
private EditText etPercent;
private ClipDrawable mImageDrawable;
private Button fly_to_50;
// a field in your class
private int mLevel = 0;
private int fromLevel = 0;
private int toLevel = 0;
//public static final int MAX_LEVEL = 10000;
public static final int MAX_LEVEL = 10000;
public static final int LEVEL_DIFF = 100;
public static final int DELAY = 0;
public static final int START_AT_50 = 50;
private Handler mUpHandler = new Handler();
private Runnable animateUpImage = new Runnable() {
#Override
public void run() {
doTheUpAnimation(fromLevel, toLevel);
}
};
private Handler mDownHandler = new Handler();
private Runnable animateDownImage = new Runnable() {
#Override
public void run() {
doTheDownAnimation(fromLevel, toLevel);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etPercent = (EditText) findViewById(R.id.etPercent);
ImageView img = (ImageView) findViewById(R.id.imageView1);
mImageDrawable = (ClipDrawable) img.getDrawable();
mImageDrawable.setLevel(0);
}
private void doTheUpAnimation(int fromLevel, int toLevel) {
mLevel += LEVEL_DIFF;
mImageDrawable.setLevel(mLevel);
if (mLevel <= toLevel) {
mUpHandler.postDelayed(animateUpImage, DELAY);
} else {
mUpHandler.removeCallbacks(animateUpImage);
MainActivity.this.fromLevel = toLevel;
}
}
private void doTheDownAnimation(int fromLevel, int toLevel) {
mLevel -= LEVEL_DIFF;
mImageDrawable.setLevel(mLevel);
if (mLevel >= toLevel) {
mDownHandler.postDelayed(animateDownImage, DELAY);
} else {
mDownHandler.removeCallbacks(animateDownImage);
MainActivity.this.fromLevel = toLevel;
}
}
public void onClick50(View v){
mImageDrawable.setLevel(START_AT_50);
}
public void onClickOk(View v) {
//int temp_level = ((Integer.parseInt(etPercent.getText().toString())) * MAX_LEVEL) / 100;
int temp_level = ((Integer.parseInt(etPercent.getText().toString())) * MAX_LEVEL) / 100;
if (toLevel == temp_level || temp_level > MAX_LEVEL) {
return;
}
toLevel = (temp_level <= MAX_LEVEL) ? temp_level : toLevel;
if (toLevel > fromLevel) {
// cancel previous process first
mDownHandler.removeCallbacks(animateDownImage);
MainActivity.this.fromLevel = toLevel;
mUpHandler.post(animateUpImage);
} else {
// cancel previous process first
mUpHandler.removeCallbacks(animateUpImage);
MainActivity.this.fromLevel = toLevel;
mDownHandler.post(animateDownImage);
}
}
}
I set my "DELAY" variable to be 0, which increased the speed a little bit, however, I am not completely satisfied with the speed and would love to increase the speed more. Is this somehow possible? And if not, is there a chance that I can create a normal progress(would work here for sure), but using my own custom edited images?
Appreciate all answers!
Thank you.
SOLVED:
I changed this line:
mDownHandler.postDelayed(animateDownImage, DELAY);
with this:
mDownHandler.postAtTime(animateDownImage,DELAY);
The code works fine but the seekbar value is not fetched in my code. The error shown is "Cannot resolve symbol progress" even after making it public. Someone throw light on this possibly with short explanation. I have stored the SeekBar value in progress and tried to use it in calculation further.
sb = (SeekBar)findViewById(R.id.set_years);
yrs = (TextView)findViewById(R.id.years);
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public int progress;
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
progress = i;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
yrs.setText(progress+" year(s)");
}
});
addButtonClickListener();
}
private void addButtonClickListener() {
submit = (Button)findViewById(R.id.submit);
submit.setOnClickListener(this);
}
#Override
public void onClick(View view) {
float loanAmtValue = 0;
float roiValue = 0;
double answer;
loanAmt = (EditText)findViewById(R.id.amt);
loanAmtValue = Float.parseFloat(loanAmt.getText().toString());
roi = (EditText)findViewById(R.id.roi);
roiValue = Float.parseFloat(roi.getText().toString());
if (loanAmtValue != 0 || roiValue != 0){
answer = (loanAmtValue * roiValue * progress) / 100;
siResult = (TextView) findViewById(R.id.result);
siResult.setText("Calculated Simple Interest for Amount Rs" + loanAmtValue + " and ROI " + roiValue + "% is = " + Double.toString(answer));
loanAmt.setText("0");
roi.setText("0");
}
else
{
siResult.setText("Please provide valid details");
}
First of all - your progress variable is member of SeekBar.OnSeekBarChangeListener anonymous inner class. You cannot access it directly without having reference to instance of this listener.
Second of all - you do not need to store the progress by yourself. Use sb.getProgress();.
Check your imports for the error "Cannot resolve symbol progress".
and check too, if you define the max for seekbar.
I am trying to figure out when a step occurs. So I have written a method called countSteps to do this. The problem with it is that I get stuck in it because with the while loop I keep getting new data and I don't think it ever returns back to onSensor. I also get an error called indexoutofboundsexception: invalid index 2,size 2.
So my first question is are there any other ways to implement the method I have without the while loop? Second is how can I fix the indexoutofboundsexception.
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mRotationVector;
private Sensor mAccelerometer;
private TextView mTextView4;
private TextView mTextView5;
private TextView mTextView6;
private TextView mTextView7;
private TextView mTextView8;
float a, b, c, d, x, y, z, xyz;
float[] retVals = new float[3];
float avg = 10;
float factor = (float) 1.15;
ArrayList<Float> accelData = new ArrayList<Float>();
public int peakCounter = 0;
public int underAvgCounter = 0;
public void countSteps() {
int n = 0;
float controlPoint = accelData.get(0);
while (accelData.iterator().hasNext()) {
if (accelData.get(n) != accelData.get(n + 1)) {
if (accelData.get(n) > accelData.get(n + 1)) {
if (accelData.get(n) < controlPoint) {
n++;
} else {
if (accelData.get(n) < avg * factor) {
underAvgCounter++;
}
peakCounter++;
n++;
}
} else {
controlPoint = accelData.get(n + 1);
n++;
}
} else {
n++;
}
peakCounter -= underAvgCounter;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView4 = (TextView) findViewById(R.id.textView4);
mTextView5 = (TextView) findViewById(R.id.textView5);
mTextView6 = (TextView) findViewById(R.id.textView6);
mTextView7 = (TextView) findViewById(R.id.textView7);
mTextView8 = (TextView) findViewById(R.id.textView8);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
accelData.add((float) 0);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_GAME);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
x = event.values[0];
y = event.values[1];
z = event.values[2];
xyz = (float) Math.sqrt((x * x) + (y * y) + (z * z));
accelData.add(xyz);
mTextView7.setText("magnitude accel " + xyz);
countSteps();
mTextView8.setText("steps " + peakCounter);
}
}
while (accelData.iterator().hasNext()) {
Is always true if you have at least 1 element in collection.
accelData.iterator() creates new iterator every time,
accelData.iterator().hasNext() checks for the first element to be in collection every time
n++ is executed until end is reached and
accelData.get(n + 1) throws IndexOutOfBoundsException
One of the things you can do is to use for loop.
for (int n = 0; n < accelData.size() - 1; n++) { // size-1 is used since you're accessing n+1 index
if (accelData.get(n) != accelData.get(n + 1)) {
if (accelData.get(n) > accelData.get(n + 1)) {
if (accelData.get(n) >= controlPoint) {
if (accelData.get(n) < avg * factor) {
underAvgCounter++;
}
peakCounter++;
}
} else {
controlPoint = accelData.get(n + 1);
}
}
}
peakCounter -= underAvgCounter;
Iterator it = accelData.iterator();
while(it.hasNext()) {
float elem = it.next();
...
}
With IndexOutOfBounds, the following code code snippets is an issue:
accelData.get(n) and accelData.get(n + 1)
You are doing a check for iterator().hasNext(), but it doesnt guarantee the existence of n+1 element.
Infinite loop, I think is because you never used iterator().next() to traverse to the next element. Please refer to a simple iterator code for better understanding.
And you can use any looping techniques like for, do while, while and advanced for loops in java, it doesnt matter. All that matters is if you are doing it efficiently and its readable.
(Sorry for My bad English, I'm Italian)
I'm new in Android Programming and I have this problem:
I need the Accelerometer data (max and min value of the sqrt(x*x..)) every "1" seconds and if the absolute value of their difference (the delta) is < of 0.4*Gravity_earth, i need the data that i acquired in the previous 5 seconds of the condition, then i calculate the max value. If the value is > of THRESHOLD i flag a "non-fall" or a "fall".
Can someone solve simply this My problem?
Thank you!
this is my solution:
public class MainActivity extends Activity implements SensorEventListener{
SensorManager sm;
float acc;
private float [] sensorData;
float azimuth,pitch,roll;
float omegaMagnitude;
//ArrayList
ArrayList<Float> tutteLeAcc =new ArrayList();
ArrayList<Float> previousAcc=new ArrayList();
Iterator<Float> it;
Iterator<Float> it1;
float accMax;
float accMin;
float accPreviousMax;
float deltaAcc;
private static final String TAG = "SIMTHR";
public static final int MSG_C = 3;
public static final int MSG_D = 4;
WorkerThread mWorkerThread;
WorkerThread1 mWorkerThread1;
boolean isRunning = false;
boolean running;
Button btnStart,btnStop;
TextView txtLog;
int tt = 0;
boolean caduta;
final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_C:
//it=tutteLeAcc.iterator();
txtLog.setText("");
txtLog.append("\nAmax: "+Float.toString(accMax)+" Amin: "+Float.toString(accMin)+" dA: "+Float.toString(deltaAcc));
tutteLeAcc.clear();
break;
case MSG_D:
txtLog.append("\nPreviousACCmax: "+Float.toString(accPreviousMax)+"\n");
//previousAcc.clear();
break;
}
caduta=Detection(previousAcc,deltaAcc);
//previousAcc.clear();
}
};
class WorkerThread extends Thread {
public Handler mCallerHandler;
private int nn = 1;
public WorkerThread(Handler handler) {
mCallerHandler = handler;
Log.i(TAG,"create WorkerThread");
}
public void run() {
nn = 0;
while(running){
try {
Log.i(TAG,"WorkerThread inizia qua");
if (mCallerHandler!=null) {
accMax=trovaMax(tutteLeAcc);
accMin=trovaMin(tutteLeAcc);
deltaAcc=Math.abs(accMax-accMin);
Thread.sleep(1000);
mCallerHandler.obtainMessage(MSG_C).sendToTarget();
Log.i(TAG,"WorkerThread finisce qua");
}
} catch (InterruptedException e) {
Log.e(TAG,"errore in WorkerThread "+e.toString());
}
}
}
public synchronized void start() {
running=true;
super.start();
Log.i(TAG,"WorkerThread avviato");
}
public synchronized void cancel() {
running=false;
Log.i(TAG,"WorkerThread avviato");
}
}
class WorkerThread1 extends Thread {
public Handler mCallerHandler;
private int nn = 1;
public WorkerThread1(Handler handler) {
// salvo l'handler dei messaggi dell'activity chiamante
mCallerHandler = handler;
Log.i(TAG,"create WorkerThread1");
}
public void run() {
nn = 0;
while(running){
try {
Log.i(TAG,"WorkerThread1 inizia qua");
if (mCallerHandler!=null) {
accPreviousMax=trovaMax(previousAcc);
Thread.sleep(5000);
mCallerHandler.obtainMessage(MSG_D).sendToTarget();
Log.i(TAG,"WorkerThread finisce qua");
}
} catch (InterruptedException e) {
Log.e(TAG,"errore in WorkerThread "+e.toString());
}
}
}
// avvio del thread
public synchronized void start() {
running=true;
super.start();
Log.i(TAG,"WorkerThread avviato");
}
public synchronized void cancel() {
running=false;
Log.i(TAG,"WorkerThread avviato");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.i(TAG,"Activity ONCREATE");
sm = (SensorManager)getSystemService(SENSOR_SERVICE);
sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
// oggetti della User Interface
btnStart = (Button) findViewById(R.id.btnStart);
btnStop=(Button)findViewById(R.id.btnStop);
txtLog = (TextView) findViewById(R.id.txtLog);
txtLog.setTextColor(Color.WHITE);
sensorData = new float[9];
// button per l'avvio del thread
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mWorkerThread!=null&&mWorkerThread1!=null) {
mWorkerThread.cancel();
mWorkerThread1.cancel();
mWorkerThread = null; mWorkerThread1 = null;
txtLog.append("\nrichiesto arresto THREAD 1 e 2 #"+Integer.toString(tt)+"\n");
}
tt++;
mWorkerThread = new WorkerThread(mHandler);
mWorkerThread1 = new WorkerThread1(mHandler);
mWorkerThread.start(); mWorkerThread1.start();
isRunning = true;
txtLog.append("\nrichiesto avvio THREAD 1 e 2\n");
}
});
// button per l'arresto del thread
btnStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mWorkerThread!=null&&mWorkerThread1!=null) {
mWorkerThread.cancel();
mWorkerThread1.cancel();
mWorkerThread = null; mWorkerThread1 = null;
txtLog.append("\nrichiesto arresto THREAD 1 e 2\n");
}
isRunning = false;
}
});
}
public void Deregistra(){
sm.unregisterListener(this);
}
public void Registra(){
sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onSensorChanged(SensorEvent event) {
float [] values = event.values;
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
sensorData[0] = event.values[0];
sensorData[1] = event.values[1];
sensorData[2] = event.values[2];
if ((sensorData[3] != 0)||(sensorData[4] != 0)||(sensorData[5] != 0)
||(sensorData[6] != 0)||(sensorData[7] != 0)||(sensorData[8] != 0))
{
float ax=sensorData[0];
float ay=sensorData[1];
float az=sensorData[2];
acc=(float) Math.sqrt((ax*ax)+(ay*ay)+(az*az));
/*
tutteLeAcc.add(acc);
accMax=trovaMax(tutteLeAcc);
accMin=trovaMin(tutteLeAcc);
deltaAcc=Math.abs(accMax-accMin);
*/
tutteLeAcc.add(acc);
previousAcc.add(acc);
}
}
else if (event.sensor.getType() == Sensor.TYPE_ORIENTATION ) {
sensorData [3] = values[0];
sensorData [4] = values[1];
sensorData [5] = values[2];
if ((sensorData[0] != 0)||(sensorData[1] != 0)||(sensorData[2] != 0)
||(sensorData[6] != 0)||(sensorData[7] != 0)||(sensorData[8] != 0))
{
azimuth=sensorData[3];
pitch=sensorData[4];
roll=sensorData[5];
}
}
else if(event.sensor.getType()==Sensor.TYPE_GYROSCOPE){
sensorData [6] = values[0];
sensorData [7] = values[1];
sensorData [8] = values[2];
final float gx=sensorData[6];
final float gy=sensorData[7];
final float gz=sensorData[8];
if ((sensorData[0] != 0)||(sensorData[1] != 0)||(sensorData[2] != 0)
||(sensorData[3] != 0)||(sensorData[4] != 0)||(sensorData[5] != 0))
{
float axisX = sensorData[6];
float axisY = sensorData[7];
float axisZ = sensorData[8];
// Calculate the angular speed of the sample
omegaMagnitude = (float) Math.sqrt((axisX*axisX) + (axisY*axisY) + (axisZ*axisZ));
}
}
}
}
public float trovaMin(ArrayList<Float> a){
Iterator<Float> it=a.iterator();
float min=a.get(0);
while(it.hasNext()){
Float x=it.next();
if(x<min){
min=x;}
}
return min;
}
public float trovaMax(ArrayList<Float> a){
Iterator<Float> it=a.iterator();
float max=a.get(0);
while(it.hasNext()){
Float x=it.next();
if(x>max){
max=x;}
}
return max;
}
public boolean Detection(ArrayList<Float> accPrec,float delta){
boolean intentional=true, static=true, lying=false;
float am;
if(delta<0.4*SensorManager.GRAVITY_EARTH){
statico=true;
Log.v("STATIC?", "yes");
if(static){
if(Math.abs(pitch)>=140||Math.abs(pitch)<30){
lying=true;
Log.v("LYING?", "yes");
if(allungato){
am=findMax(accPrec);
if(am>2.5*SensorManager.GRAVITY_EARTH||omegaMagnitude>200){
intentional=true;
Log.v("INTENTIONAL?", "yes");
}else{
intenzionale=false;
Log.v("INTENTIONAL?", "no");
}
}
}else {
lying=false;
Log.v("STANDING?", "yes");
}
}
} else {
static=false;
Log.v("STATIC?", "no");
}
if(static&&lying&&!intenional)
return true;
else return false;
}
}
There is no exact way of telling which samples are got which second. but you can approximate it by fixing frequency at which you get accelerometer updates.
Lets say we request 50 samples for second (50 hz)
for this
sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),50000000);
Dont use android sensor delay constants(i.e SensorManager.SENSOR_DELAY_NORMAL) they are different for different vendor devices.
Now just run a simple counter 0 to 50 (no other way :()
I hope this helps you.
my advice is to run the sensor at the maximum possible frequency:
sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_FASTEST);
because, any way, the rate indicated with a number is not strictly observed by the device in any case; besidesm that "numeric" rate is supported only since API v.2.3.
Then, you should write the onSensorChanged method like that.
Comment: you check if the current time is more than the latestSensorChange + DELTASENSOR (that is the number of milliseconds you want to wait between to Sensor values).
#Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
long Now = System.currentTimeMillis();
if (Now > (latestSensorChange + DELTASENSOR)) {
/* if ((mDbHelper.getOldVal(BreathDbAdapter.IDX_X) != values[BreathDbAdapter.IDX_X]) ||
(mDbHelper.getOldVal(BreathDbAdapter.IDX_Y)!= values[BreathDbAdapter.IDX_Y]) ||
(mDbHelper.getOldVal(BreathDbAdapter.IDX_Z)!= values[BreathDbAdapter.IDX_Z])) {
*/
msg = "Accelerometer: " + values[0]
+ ", " + values[1] + ", " + values[2] + " at " + Now + " (EndTime =" + EndTime +")";
mTextViewAccelerometer.setText(msg);
Log.v(TAG, msg );
latestSensorChange = Now;
if (Now > EndTime) {
Log.v(TAG,"Fine del Test at " + Now);
finish();
}
}
Please, let me know if it helps (sennò ti vengo a cercare perchè sono Italiano anch'io :-) )
Checco