For my regions science fair, I am making a speedometer app for Android and I want to set a speed limit. Here is the code I'm having trouble with:
public void onLocationChanged(Location location) {
TextView txt = (TextView) this.findViewById(R.id.textView1);
if (location==null)
{
txt.setText("-.- km/h");
}
else if (location == 1.50)
{
txt.setText("Warning");
}
else
{
float nCurrentSpeed = location.getSpeed();
txt.setText(nCurrentSpeed*3.6 + " km/h");
}
}
I want to make it so that when the speed 1.50 km/h it changes the text to "Warning". I keep getting Incompatible operand types Location and double. I have tried doing this
else if (nCurrentSpeed == 1.50)
{
txt.setText("Warning");
}
But it still gives me the same error, but modified Incompatible operand types float and double. Is there any tips on how to solve this or how to create a speed limit for a speedometer?
The location object is not just a primitive object, but its contents is not know here.
However based upon later code, you are showing that it has
location.getSpeed()
so change your code to
else if (location.getSpeed() == 1.50)
I would also suggest that you use >= 1.5
shouldn't it just be something like
public void onLocationChanged(Location location) {
TextView txt = (TextView) this.findViewById(R.id.textView1);
if (location==null)
{
txt.setText("-.- km/h");
}
else if (location.getSpeed() >= 1.50f)
{
txt.setText("Warning");
}
else
{
float nCurrentSpeed = location.getSpeed();
txt.setText(nCurrentSpeed*3.6 + " km/h");
}
}
i.e. you need to compare location.getSpeed() with 1.5, not the whole location Object
Related
I'm trying to take the target (initiated as ImageView) id and put the integer id into a switch case to look at the adjacent Views and compare their drawables to determine if that player wins or if the game continues. I have the buttonPressed variable initiated as an Integer and used the parseInt() to get the int value of target.
public void compareButton(int buttonPressed){
//int count = 0;
ImageView adjacent;
ImageView adjacentB;
switch (buttonPressed){
case R.id.imageButtonA: //this is where adjacent buttons are identified and compared
adjacent = findViewById(R.id.imageButtonB);
adjacentB = findViewById(R.id.imageButtonC);
if (target.getDrawable() == adjacent.getDrawable() && target.getDrawable() == adjacentB.getDrawable()) {
Toast.makeText(MainActivity.this, "You Win!", Toast.LENGTH_SHORT).show(); //Win condition
// } else if (target.getDrawable() == R.id.imageButtonE.getDrawable() & target.getDrawable() == R.id.imageButtonI.getDrawable()) {
//Toast.makeText(MainActivity.this, "You Win!", Toast.LENGTH_SHORT).show(); //Win condition
// } else if (target.getDrawable() == R.id.imageButtonD.getDrawable() & target.getDrawable() == R.id.imageButtonG.getDrawable()) {
//Toast.makeText(MainActivity.this, "You Win!", Toast.LENGTH_SHORT).show(); //Win condition
}
break;
case R.id.imageButtonB:
break;
I am not filling every case for debugging purposes.
The issue I am having is when I run the emulator I get an error that says
Caused by: java.lang.NumberFormatException: For input string: "androidx.appcompat.widget.AppCompatImageButton{517eade VFED..C.. ...P..ID 45,381-304,628 #7f070072 app:id/imageButtonA}"
at java.lang.Integer.parseInt(Integer.java:521)
at java.lang.Integer.parseInt(Integer.java:556)
at com.example.connect3.MainActivity.switchColor(MainActivity.java:75)
Here is the code for the OnClickListener:
public void switchColor(View view) {
//Button pressed, depending on user, switch's to that users color; identify adjacent button ID's; toast player control switch
if (player == 1) {
source = findViewById(R.id.yellow);
target = findViewById(view.getId());
target.setImageDrawable(source.getDrawable());
buttonPressed = Integer.parseInt(target.toString());
compareButton(buttonPressed);
player++;
Toast.makeText(MainActivity.this, "Player 2's Turn!", Toast.LENGTH_SHORT).show();
} else {
source = findViewById(R.id.red);
target = findViewById(view.getId());
target.setImageDrawable(source.getDrawable());
buttonPressed = Integer.parseInt(String.valueOf(target));
compareButton(buttonPressed);
player--;
Toast.makeText(MainActivity.this, "Player 1's Turn!", Toast.LENGTH_SHORT).show();
}
Not entirely sure what is going on at this point because I thought I did everything correct but clearly something was missed. Any help would be appreciated.
change :
buttonPressed = Integer.parseInt(String.valueOf(target));
To :
buttonPressed = target.getId();
Explanation : your error says NumberFormatException means you are trying to get int value from String which is not possible to Parse or in simple your string doesn't contain proper int value and also you are passing (androidx.appcompat.widget...) as string while you have to pass button I'd
I don't event know how to describe this weird behaviour i'm dealing with right now, but the thing is:
I have a class Player.java that has a private float life, pretty basic.
this float has its setter / getter and there is NO other way of retrieving / attributing this variable without using the getter / setter.
also, i have put a println in each, so i can have a feedback of when this variable is being retrieved, and when is beign attributed, and i get THIS on my console:
my console
i don't think the stack trace is usefull in any way, but if you want to, i can paste the code behind the stack trace too
anyway, if you haven't notice, there is a retrieve of life = 61, FOLLOWED by a retriving of life = 70, with NO attribution WHATSOEVER of this variable back to 70.
also, i dont know if this is useful, but here is the code that prints the "1 damaged 0, broadcasting to clients - Sent":
it resume in:
- decreases the player life
- if it has died, mark as dead and do other little effect things
- send event to google analytics
- after all that, if the game is a server, broadcast the damage event to all clients
public void takeDamage(float amount, Player owner, boolean showBlood, boolean local){
if(local && KambojaMain.getInstance().multiplayerConnection && !KambojaMain.getInstance().isServer) return;
if(imunity <= 0){
//new Exception().printStackTrace();
setLife(getLife() - amount * def);
if(owner != null) {
owner.score += amount*def;
}
if(showBlood)
state.showBlood(body.getWorldCenter());
System.out.println(" - DAMAGE DETECTED from " + owner.getId() + " to " + getId() + " with value " + amount + ", it was a local? " + local + ", and show blood is: " + showBlood);
System.out.println("target life is now at " + getLife());
hitTimer = 1f;
if(getLife() <= 0){
if(!isDead()){
deaths++;
if(owner != null){
owner.kills ++;
owner.ghosts.add(new Ghost(getId(), getPosition()));
owner.score += 100;
}
setDead(true);
body.getFixtureList().get(0).setSensor(true);
getState().showSkull(body.getWorldCenter(), getAngle());
String playerType = "controller";
if(isKeyboard()) {
playerType = "keyboard";
}
if(this instanceof BetterBot) {
playerType = "bot";
}
HashMap<String, String> customs = new HashMap<String, String>();
customs.put("cd1", KambojaMain.getMapName());
customs.put("cd3", getWeapon().getClass().getSimpleName());
customs.put("cd4", "player_" + playerType);
String ow = "Suicide";
if(owner != null)
ow = owner.getWeapon().getClass().getSimpleName();
KambojaMain.event("game", "player_kill", ow, customs);
}
}
if(gruntTimer < 0){
if(GameState.SFX)
grunt[(int)(Math.random()*5)].play();
gruntTimer = 0.5f;
}
if(KambojaMain.getInstance().multiplayerConnection && KambojaMain.getInstance().isServer) {
KambojaPacket kp = new KambojaPacket(PacketType.PLAYER_DAMAGE);
PlayerDamage pd = new PlayerDamage();
pd.damage = amount;
pd.showBlood = showBlood;
pd.owner = owner.getId();
pd.target = getId();
kp.data = pd;
System.out.print(pd.owner + " damaged " + pd.target + ", broadcasting to clients - ");
KambojaMain.getInstance().broadcast(kp, Protocol.TCP);
System.out.println("Sent");
}
}
}
note: i AM using multi threading environment because this is a lan multiplayer game, and this variable can be retrieved in other threads different from the main thread.
I have searched about the volatile keyword, Atomic classes (AtomicFloat dont exist, and the implementation of it using AtomicInt as a bit data also was used), but none of this could prevent this from happening and i have NO idea of what is this behaviour and what is causing it
can someone please help me? i don't know what to search anymore
Try making your method synchronized (this would make sure only one thread can be running this method, on an instance of your class).
public synchronized void takeDamage(.... // same as before
Check out this post, it has a similar question with more info about running blocks of code atomically.
I'm creating a simple app that calculates BMI and I'm struggling with one small problem. I have 2 edit text fields, which are allowed to type numbers only. The point is when one of the text fields are empty the app is to generate a toast message and display nothing. I wrote an if statement to check if an edit text is empty and if not just to calculate further.
All would work fine, but I needed to put return statement and Android Studio suggested me writing "return 0;" so did I.
This is the code responsible for calculations:
/// parse input value from edittext field into double type
private double weight() {
EditText weightInput = (EditText) findViewById(R.id.weight_input);
String sWeightInput = weightInput.getEditableText().toString();
if (sWeightInput.matches("")){
Toast.makeText(this, R.string.noweight, Toast.LENGTH_SHORT).show();
} else {
String weight = sWeightInput;
double weightTyped = Double.parseDouble(weight);
return weightTyped;
}
return 0;
}
private double heigh() {
EditText heightInput = (EditText) findViewById(R.id.height_input);
String sHightInput = heightInput.getEditableText().toString();
if (sHightInput.matches("")){
Toast.makeText(this, R.string.noheight, Toast.LENGTH_SHORT).show();
} else {
String height = sHightInput;
double heightTyped = Double.parseDouble(height);
heightTyped = heightTyped / 100;
heightTyped = heightTyped * heightTyped;
return heightTyped;
}
return 0;
}
//make calculations and return the output value
public void makeCalculations(View view){
double result = weight() / heigh();
String message = String.valueOf(result);
TextView bmiSummaryTextView = (TextView) findViewById(R.id.bmi_calculation);
bmiSummaryTextView.setText(message);
}
This is the interface of the app.
To sum up, all I want to do is to display nothing instead of NaN (not a number).
Return a non-primitive Double rather than a double, and you will be able to use null as a value. Be sure to check for this value though, or you'll run into a NullPointerException.
Alternatively, you could look into using optionals, but since you're using Android you might need an external library for that (unless your minimum SDK version is high enough, then you can use Java 8's Optional).
The problem is probably if in your calculation weight() / height height is 0 it outputs NaN because it is infinity.
Also put your return 0; after Toast.makeText() in the condition. AS grumbles because you are not returning a value in the if branch.
if (sHightInput.matches("")){
Toast.makeText(this, R.string.noheight, Toast.LENGTH_SHORT).show();
return 0;
}
Maybe this will help you also to avoid dividing by zero.
public void makeCalculations(View view) {
String message = "Invalid input!";
if (weight() > 0 && height() > 0) {
double result = weight() / heigh();
String message = String.valueOf(result);
}
TextView bmiSummaryTextView = (TextView) findViewById(R.id.bmi_calculation);
bmiSummaryTextView.setText(message);
}
I want to know how I can use accelerometer sensor to determine distance that I an walk it at Android device If it is possible, then how can I implement it?
I use this code but not run. Any answer please??
#Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
int value = -1;
if (values.length > 0) {
value = (int) values[0];
}
if(event.sensor.getType()==Sensor.TYPE_STEP_DETECTOR) {
steps++;
}
}
float distance = (float)(steps*68.475)/(float)100000;
It is not possible: due to the low sensitivity of the built-in accelerometers and the so weak accelerations that are created when a person walks.
Not having network does not mean that GPS does not work ...
Im listening to my phones GPS and post latitude and longitude to my webservice evey time onLocationChanged gets called. My problem is that in about 2% of my posts, it displays a VERY inaccurate result (several miles off). Should i check the accuracy from my location object before i post? Or do you have any other suggestions? Thanks!
public void onLocationChanged(Location location) {
locationManager.removeUpdates(networkLocationListener);
textView.setText(textView.getText().toString() + "New GPS location: "
+ String.format("%9.6f", location.getLatitude()) + ", "
+ String.format("%9.6f", location.getLongitude()) + "\n");
//float accuracy = location.getAccuracy(); check this value?
postLocationToWebservice(location);
}
This is a very common problem while using the Location services of Android.There are few checks you can introduce to make sure that only the accurate location gets posted to you web service.
1.Compare the accuracy of all the location services.
2.Define a minimum limit for accuracy and a maximum limit for time.(Because some times the location obtained is accurate but it is an old one).
Check this code snippet and make necessary changes to accomplish what you want.Make sure you make a
log build that checks the accuracy of your algorithm.
List<String> matchingProviders = myLocation.lm.getAllProviders();
for (String provider: matchingProviders)
{
Location location = myLocation.lm.getLastKnownLocation(provider);
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
if ((time > minTime && accuracy < bestAccuracy)) {
bestResult = location;
bestAccuracy = accuracy;
bestTime = time;
}
else if (time < minTime && bestAccuracy == Float.MAX_VALUE && time > bestTime) {
bestResult = location;
bestTime = time;
}
}
}
It could be possible that the updated location is reported by NETWORK_PROVIDER instead of GPS_PROVIDER
you can always get the last updated GPS location by
mLocationMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);