I am trying to make a counter that counts how many times the proximity sensor is triggered in Android.
But the problem that I am facing is, the counter counts twice every time the proximity sensor is triggered.
First, for the entry time and second for the exit time.
The code that I have so far is
public void onSensorChanged(SensorEvent event) {
textView1 = (TextView) findViewById(R.id.textView2);
if (event.values[0] == 0) {
} else {
counter++;
textView1.setText(""+counter);
}
}
For instance if the sensor is triggered the counter variable returns value of 2, how do I correct it?
Any help is appreciated.
Please note that sensor is triggered when something is close to it (e.g. hand, face, any object) and when you move object away. It means, when you put your hand close to the sensor and immediately move it away, sensor will be triggered two times. Sensor should give you two values: one for the situation, when object is close to the sensor and another one when nothing is close to the sensor. One of the values from the SensorEvent changes. I don't remember which one. You should check, which value changes and what are sensor readings for situation when object is close and when there's no object. After that, you can use this value inside the conditional "if" statement depending on the fact which moment you want to detect (object is moved close to sensor or object is moved away from the sensor).
Related
I have a variable whose value can change as frequently as the device frame-rate. Now, actually it is an angle, but perhaps can be thought of as a regularly incrementing value. What I wish, is to calculate how many 360 loops have been made. I have a Composable, which I have hooked up to this value. So the user is basically rotating an indicator, and I update the value based on the angle. Now, I already have a system put in place which performs a calculation on the indicator position and renders an angle ranging from 0 to 359 (well 360 actually, but non-inclusive). So, now if the user is spinning the indicator, I want to know when he actually hits the 0f Angle. I tried it with a conditional but this does not work if the user is going even at a reasonable speed. He must be incredibly slow in order to capture that value.
Here's a sample
val angle = ...//Already Got this Value
if(angle == 0f) { /*One cycle Complete*/ } // But this is not detected mostly
Now, remember that this is Compose, so we must take recompositions into account. I have tried with a list, by storing some of the latest values of the variable, but it just rotates too fast. All the values end up being the same, unless the size is crazy like 500 or so.
Can my approach be better? Any known way of accomplishing this without changing the approach. Basically any help would be appreciable.
This is what I ended up doing and it works at any given speed
var cycles by remember { mutableStateOf(0) } // Holds cycles state
val startCheck by mutableStateOf(angle in 300..360) //The Hot-Zone for Active Monitoring
LaunchedEffect(angle) { //This executes every time angle changes, i.e, at frame rate
if (startCheck) { //Only if indicator is in the hot zone
if (angle <300 ) cycles++ //Increment the Cycles
}
}
Using Androids sensor libs it is possible to extract the steps taken in a trigger function called "onSensorChanged".
#Override
public void onSensorChanged(SensorEvent event) {
String steps = String.valueOf(event.values[0]);
...
}
The array "event.values[0]" will hold the current steps taken since last phone reboot as the Android Dev Docs says. Beginning to walk will call "onSensorChanged", and the steps can be collected.
Is there a way to collect the last known step count without calling "onSensorChanged" or even walking from inside any onCreate method or alike?
Example imaginary code:
SensorEventValues sev = new SensorEventValues();
Toast.(This,sev.values[0],Toast.LENGTH_LONG).show();
I have a group of objects within a game that is a sensor(let's call them collectively object1). When it collides with my main object (object2), the score increments by 10. However, after each subsequent restart of the scene(not the whole game), each collision between object1 and object2 duplicates itself, then triplicates and so forth.
So for the first running of the scene, object1 collides with object2 once(I know this because I have a print statement every time the 2 objects collide). The second time it collides twice, the third time three times and so forth. I presume I am not removing a certain feature of the sensor but I cannot figure out what it is. How do I correctly remove the objects if this is the problem?
My code for the removal of object1 on collision:
local function onCollision( self,event )
if(event.object2.name == "bonus")then--if we hit a bonus ball
event.object2:removeSelf()--removes the bonus ball object from the scene
print("bonus collided")
display.remove(event.object2)
game.addToScore(10)--adds a value of 10 to the score
scoreText.text = game.returnScore()
Runtime:removeEventListener("enterFrame", event.object2)
else
composer.gotoScene("restart")
Runtime:removeEventListener("touch", onObjectTouch)
end
end
I studied your code and in short this is the problem
ball.collision = onCollision
It's located under scene:show and therefore a new eventListener will be created each time that you to the scene. And it's not being removed under scene:hide.
Basically half of your code doesn't really do anything. For exampel you remove the same item twice, add Runtime listeners to objects (not functions) and you're trying to remove thise Runtime listeners. For example this tries to remove a Runtime event listener on a display object that doesn't even exist:
Runtime:removeEventListener( "collision", circle )
What you need to do is:
Create all objects and listeners under scene:create
Use local collision handling (i.e. not Runtime listeners): https://docs.coronalabs.com/daily/guide/physics/collisionDetection/index.html#local-collision-handling
Rewrite your code so that you have functions and listeners outside of the scene:create
I want to create a condition to wait for a broadcast upon a button press
right now I am just doing solo.sleep(10000)
but I dont want to sleep solo for nothing
How do I formulate the condition "broadcast received" ?
Ok explanations
Robotium Solo is an instrumentation framework with nice api
It has a method called "solo.waitForCondition(Condition, int timeout)"
I want to formulate (the word formulate means say what i want to say in correct words)
the correct condition that will tell me that the broadcast was indeed received
I want to write some code (I don't know which exactly) to know that the broadcast was indeed sent
for example, if i want to know that a button is now visible i would write
solo.waitForCondition(new Condition(){
public boolean isSatisfied(){
Button b = getActivity().findViewById(R.id.myButton);
return b.getVisibility() == View.VISIBLE;
}
}
now back to my question - What (not how, but what) do I write in order to know for sure that the broadcast was sent inside the isSatisfied method
I suppose you meant that you don't want to sleep for 10 seconds, if you get the broadcast earlier. What you can do is
long beginTime = new Date().getTime();
while (new Date().getTime() - beginTime < 10000) {
solo.sleep(500);
if (conditionMet) {
// Do something
break;
}
}
This way you can do these checks on smaller intervals.
Ok, so in fact this is more or less how waitForCondition is implemented. Unfortunately I don't think you can listen for events with robotium. What you can do is monitor the view hierarchy. In your case, there should be some difference to the views that is triggered when the button is clicked, so that is what you need to check for in the Condition (and your example does that).
This is if you don't want to edit the code you are testing. If you are willing to change the code, you can add an onClickListener() and in that you can set a view's Tag to a boolean for example. Later in robotium you can check for that tag for being set. This is however not good way to do it, because you are adding more code just for the sake of the tests.
So, I have plotted a GPX route in my MapView, and I am listening for location changes.
Ultimately I want to give my user notification when they are off/on course.
So, I can imagine just brute-force going through all my GPX coordinates and do a Location.distanceTo for each for each of them. But that seems expensive.
I could reduce the cost by doing it infrequently.
I am wondering if someone has a clever idea for achieving this?
You can use the function distanceTo but not inside onLocationChanged (because it is called very frequent) , you should do a timer and check if the user going off course in each 5 seconds (for example), this is how to implement the timer:
1- declare this as global variable:
private Timer myTimer;
2- add this code in your onCreate():
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, 5000);
3- add these two functions in your class:
private void TimerMethod()
{
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
//do your test for off course here
}
};
Good luck
I would probably keep track of three coordinates: Last, Current, Next. You can calculate the distance and direction from Last to Current and the location and direction the user is going and come up with some algorithm to ensure the user is going the right way (ensure that the user is approaching Current, ensure that they're within some distance of the line from Last to Current, etc.)
Then at some point you need to realize that the user has come as close as they're ever going to towards Current and are now heading for Next. Then you'll shift the points down (Last = Current; Current = Next; Next = ???;). Again there are a number of ways you could make this determination (user has gotten close enough to Current, user is heading towards Next and away from Current, etc.)
You might want to include some look-ahead in case you miss a few points, especially when points are close together, but you don't want to do too much. Test your route with loops in the paths and make sure you don't jump ahead. You'll probably also need to implement some sort of holyExpletiveIHaveNoIdeaWhereTheUserIsGoing() method to recover from the (inevitable) errors.