How to detect "in call mode" android java - java

I'm trying to detect mode when we in call. I'm using most popular example with broadcast and telephonyManager.
But there are only 3 states.
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
}
if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
}
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
}
after some tests i found that :
1) when incoming call - than i see state = RINGING
- accept call from this state = OFFHOOK
2) but when im do outgoing call - state = OFFHOOK , and when another "me" on other side accept call - state still = OFFHOOK.
How to correctly detect IN_CALL_MODE (mean im speaking at current time ). ?
Can any help ?

How about using AudioManager??
AudioManager manager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
if(manager.getMode()==AudioManager.MODE_IN_CALL){
return true; // Active call
}
else {
return false;
}

Related

How to use "conditionals" without using IF statements?

I have this project that we can't use IF statements for. For example, if something is connected this needs to happen. So I made a variable connected and initialised it to 0. To say, if something is connected then it's 1 and if it's not its 0. But i cant figure out how to write the statements to say that without using if statements.
public void removeBattery(){
connected = 0;
cameraCharge = cameraCharge * connected;
}
But this isn't working in the tests when I call the method. Even though, its multiplied by 0 its still showing a different value.
public double drain(double minutes) {
double drain = Math.min((cameraPowerConsumption * minutes),
batteryCharge);
batteryCharge = Math.max(batteryCharge - drain, 0);
totalDrain += drain;
return drain;
}
And here if its connected this is how you calculate drain, but when you call the removeBattery method it shouldnt be connected anymore and the drain should be 0. Im so confused.
The logical AND operator && can be included in your code to examine the status of the declared variable 'connected'. When the value of 'connected' is 1, the expression 'connected == 1 &&' will evaluate to true, while it will return a false result if the value is something else. This can be incorporated in the 'drain' method to control the calculation of the drain in response to the status of 'connected'. For example, it can be written as such:
public double drain(double minutes) {
double drain = connected == 1 ? Math.min((cameraPowerConsumption * minutes),
batteryCharge) : 0;
batteryCharge = Math.max(batteryCharge - drain, 0);
totalDrain += drain;
return drain;
}
If the connection is established, the amount of drain will be determined as normal. On the other hand, if the connection is not made, the drain value will be set to zero.

How to keep track of changed values

I have a bluetooth device which keeps emitting data when it is started and stops emitting data when it pauses, I have RXJava subscriber attached to it to get the values.
What I want to do is check if the device is still running or paused. So for this I have a method getTotalizerChangedTime, this gives me the last updated time.
Based on getTotalizerChangedTime I want to check if the device is still running or not.
I want to check lastUpdatedTotalizerChangeTime and calculator.getLastTotalizerChangeTime() and if they both are same and time difference between them is 8 seconds (as every 8 seconds or so I get a value)
lastTotalizerChangeTime - 2019-09-04T18:33:40.781+01:00
lastTotalizerChangeTime - 2019-09-04T18:33:47.080+01:00
lastTotalizerChangeTime - 2019-09-04T18:33:57.592+01:00
lastTotalizerChangeTime - 2019-09-04T18:34:03.683+01:00
What I have tried is, I declared a variable to keep the last updated
private DateTime lastUpdatedTotalizerChangeTime = new DateTime();
I created a function which get the lastTotalizerChangeTime from getLastTotalizerChangeTime and does the following but does not work as expected.
Function that get the actual value
public DateTime getLastTotalizerChangeTime() {
return lastTotalizerChangeTime;
}
I have declared a variable to keep the lastUpdatedChangedTime
private DateTime lastUpdatedTotalizerChangeTime = new DateTime();
Bellow is the function that gets called on button click which checks if the device is still running
private boolean hasFlowMeterFinishedPumping(){
DateTime currentTime = new DateTime();
Period differenceX = new Period(calculator.getLastTotalizerChangeTime(), currentTime);
if(differenceX.getSeconds() >= 8 && lastUpdatedTotalizerChangeTime.equals(calculator.getLastTotalizerChangeTime())){
Log.d("totaliserSenseCheck", "IF");
lastUpdatedTotalizerChangeTime = calculator.getLastTotalizerChangeTime();
return true;
}else{
Log.d("totaliserSenseCheck", "else");
lastUpdatedTotalizerChangeTime = calculator.getLastTotalizerChangeTime();
return false;
}
}
Logic I have written to track if the device stopped does not work as expected.
Your help much appreciated.
R

Java: If-else statement

I made a twitch irc bot.
I have setup a little "system" to turn itself on whenever the stream is going online and should turn off when the stream isnt online anymore.
im using the following code:
if (TwitchStatus.isstreamlive && multistartprepare == false && multistartprepare2 == false){
livemode = true;
multistartprepare = true;
startedAt = DateTime.now();
startup();
}else{
if (TwitchStatus.isstreamlive == false && multistartprepare){
livemode = false;
multistartprepare = false;
multistartprepare2 = false;
TTmsg.cancel();
TTmsg.purge();
}
}
isstreamlive is a boolean which is either true when a stream is live or false when the stream is offline.
isstreamlive gets updated every 5 secons by making a JSON request and holds the right value the whole time.
the problem now is that the startup() Method will activate a timer for a greeting message in the irc chat. Somehow it happens the timer got executed 2 or 3 times when i start my bot so i guess something is wrong with my if else statement.
the booleans multistartprepare and multistartprepare2 are false on start and are there for the bot to start only once a time, til the stream is over and he can get offline.
is there something wrong above? Guess the code gets executed to many times.
greetings and sorry for bad english :D
It might help if you use your livemode variable in the if as well
if (TwitchStatus.isstreamlive &&
!multistartprepare &&
!multistartprepare2 &&
!livemode) {
You might be able work around this by setting up a timeout that prevents your bot from sending the message if it's been sent in the past few seconds.
long lastSent = 0;
...
if (System.currentTimeMillis() - lastSent > 1000*5) { // 5 seconds elapsed
...
// send message
lastSent = System.currentTimeMillis();
}
You might have something wrong with your setup method, or the server might be sending you multiple went-online messages, but it's hard to tell based on the info you have so far.

Google Play Game Services unlock achievement - store unlock in game or call unlock() every time?

I am developing an Android game which uses Google Play Game Services.
When a player reach for example 10000 points an achievement gets unlocked.
So when the player reaches 10000 points I call
Games.Achievements.unlock(...)
The question is what to do when the user reaches 10000 points again in another game. Do I have to check if this achievement is already unlocked or can I just call unlock() again?
I know that the Play Services popup is diplayed only when the achievement gets first unlocked. But I am concerned about the quota of api calls. If I for example store the achievement unlock from shared preferences then I would do something like this:
if(myAchievementIsLocked){
Games.Achievements.unlock(...)
}
What are the best practices? I was looking at some samples but didn't find the answers which I was looking for.
As far as I can tell, unlock() will check with the local Play Games app first to see if the achievement is already unlocked, and only if it is not will it send the request to the server. This means that calling unlock() on an already unlocked achievement should not affect any quotas apart from the first time it is called on a device - since the device's instance of the Play Games may not have synced that achievement from the server yet.
On the other hand, it is possible to check the state of all achievements after signing-in and keeping a local copy of their states - which indeed you should do if the player is NOT signed-in (so that you can unlock any achievements earned at the next sign-in). This process is not documented well anywhere except for the API documentation but there are no full examples, so I will give you one here :)
Ensure that you run this method asynchronously (using AsyncTask or a separate thread) as it will take some time to complete (waiting for responses from the server). Also, do this only when the player is signed in successfully - onSignInSucceeded() is a good place for it.
Update for Play Service Games 11.8.0
public void loadAchievements() {
mAchievementsClient.load(true).addOnCompleteListener(new OnCompleteListener<AnnotatedData<AchievementBuffer>>() {
#Override
public void onComplete(#NonNull Task<AnnotatedData<AchievementBuffer>> task) {
AchievementBuffer buff = task.getResult().get();
Log.d("BUFF", "onComplete: ");
int bufSize = buff.getCount();
for (int i=0; i < bufSize; i++) {
Achievement ach = buff.get(i);
String id = ach.getAchievementId();
boolean unlocked = ach.getState() == Achievement.STATE_UNLOCKED;
}
buff.release();
}
});
Older Play Service Games
public void loadAchievements() {
boolean fullLoad = false; // set to 'true' to reload all achievements (ignoring cache)
float waitTime = 60.0f; // seconds to wait for achievements to load before timing out
// load achievements
PendingResult p = Games.Achievements.load( playHelper.getApiClient(), fullLoad );
Achievements.LoadAchievementsResult r = (Achievements.LoadAchievementsResult)p.await( waitTime, TimeUnit.SECONDS );
int status = r.getStatus().getStatusCode();
if ( status != GamesStatusCodes.STATUS_OK ) {
r.release();
return; // Error Occured
}
// cache the loaded achievements
AchievementBuffer buf = r.getAchievements();
int bufSize = buf.getCount();
for ( int i = 0; i < bufSize; i++ ) {
Achievement ach = buf.get( i );
// here you now have access to the achievement's data
String id = ach.getAchievementId(); // the achievement ID string
boolean unlocked = ach.getState == Achievement.STATE_UNLOCKED; // is unlocked
boolean incremental = ach.getType() == Achievement.TYPE_INCREMENTAL; // is incremental
if ( incremental )
int steps = ach.getCurrentSteps(); // current incremental steps
}
buf.close();
r.release();
}
See the API documentation for more info on these processes.
So using this method you could create a local copy of the achievements (just alter the internals of the for loop to save the achievement values to some local structure) and refer to it as needed.
Calling .unlock(...) on an already unlocked achievement shouldn't be a problem. My guess is there is already some sort of "check if unlocked" handling in the .unlock(...) method.

How to check if a body has almost stopped moving in libgdx + box2d

So, I have a player body + fixture etc, it is essentially a ball that bounces around.
I want to detect when it is 'pretty much' finished moving.
At the moment I do this:
public Boolean isStopped() {
return body.getLinearVelocity().x <= 0.3f && body.getLinearVelocity().y <= 0.3f;
}
This mostly works, the problem being when the player hits something, there's a split second where its velocity is 0, so this returns true. What I really wanted is to just return true when it is basically finished. Preferably within a range that I can set to whatever I like as I tweak the physics of my game world.
I can't use a check on whether it is sleeping or not as that comes too late, it doesn't sleep until after it has stopped having forces act upon it, I need just before.
I could just store how long it has been stopped/a count of stopped steps, but I was hoping there would be a nice pre existing method that I missed.
Any ideas?
You can keep track of recent movement and update it by mixing in a little of the current speed each time step:
float speedNow = body.getLinearVelocity().len();
recentSpeed = 0.1 * speedNow + 0.9 * recentSpeed;
if ( recentSpeed < someThreshold )
... do something ...
You would need to set recentSpeed to a suitably high value to begin with, otherwise it might be below the threshold in the first time step.
Seeing how you've determined that your false positives are caused by the body making contact with another, why not add a couple of lines in your ContactListener's beginContact method, storing the body's current speed in its user data? Then you can check that speed in your isStopped method. If there is a stored speed and the current speed isn't greater, this means the body is in the process of bouncing off whatever it hit: ignore. If there is a stored speed and the current speed is greater, the ball has bounced and is proceeding in some new direction: clear the stored speed. If there is no stored speed and the current speed is below your threshold, you've detected the sought situation.
In your ContactListener:
public void beginContact(Contact contact) {
Body a = contact.getFixtureA().getBody();
Body b = contact.getFixtureB().getBody();
if (a == mBall) {
a.setUserData(a.getLinearVelocity().len());
} else if (b == mBall) {
b.setUserData(b.getLinearVelocity().len());
}
}
And in your isStopped check:
public Boolean isStopped() {
float storedSpd = (Float) body.getUserData();
float currentSpd = body.getLinearVelocity().len();
if ((storedSpd > Float.MIN_VALUE) && (currentSpd > storedSpd)) {
body.setUserData(Float.MIN_VALUE);
return false;
} else {
return (currentSpd < THRESHOLD);
}
}
This is untested, but you get the idea. Also, remember to initially set the user data to Float.MIN_VALUE.
In the end I have simply passed the delta from each render call to the isStopped() method.
public Boolean isStopped(float delta) {
boolean isMoving = (
Math.abs(body.getLinearVelocity().x) >= 0.25f || Math.abs(body.getLinearVelocity().y) >= 0.25f);
if(isMoving) {
timeStopped = 0f;
return false;
} else {
timeStopped += delta;
return timeStopped >= 0.3f;
}
}
timeStopped is just a class property that starts off as zero. This does return true for the beginning of the game (before the user has made a move) but in my application that is absolutely fine. Besides which, it is true to say it has stopped in that circumstance.
I'd still love to see a way to do this without storing extra crap, since I'm guessing box2d must have this information somewhere in order to figure out if a body with zero velocity has no force acting upon or if it is just changing direction after an impact.

Categories