How get battery temperature with decimal? - android

How can i get the battery temperature with decimal? Actually i can calculate it with
int temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0);
But in this way the result will be for example 36 °C.. I want something that show me 36.4 °C How can i do?

Google says here :
Extra for ACTION_BATTERY_CHANGED: integer containing the current battery temperature.
The returned value is an int representing, for example, 27.5 Degrees Celcius as "275" , so it is accurate to a tenth of a centigrade. Simply cast this to a float and divide by 10.
Using your example:
int temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0);
float tempTwo = ((float) temp) / 10;
OR
float temp = ((float) intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0) / 10;
You don't need to worry about the 10 as an int since only one operand needs to be a float for the result to be one too.

public static String batteryTemperature(Context context)
{
Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
float temp = ((float) intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0)) / 10;
return String.valueOf(temp) + "*C";
}

That's the only way I know you can get the battery temperature, and is always an int.
According to documentation:
public static final String EXTRA_TEMPERATURE
Extra for ACTION_BATTERY_CHANGED: integer containing the current battery
temperature.
But you can divide by 10.0f to get one decimal.
float ftemp = temp/10.0f;

Related

Rounding to two decimal places in Android

Should be simple I know but I cant find an answer anywhere. I'm trying to round up to two decimal places, so if my answer is 164.9835 I'd like the answer to be displayed as 164.99. But what I have so far is rounding it to 164.98 for some reason.
Any help much appreciated.
double number1 = Double.parseDouble(num1.getText().toString());
double number2 = Double.parseDouble(num2.getText().toString());
double number3 = Double.parseDouble(num3.getText().toString());
double number4 = Double.parseDouble(num4.getText().toString());
double sum = (((number1 * number2)/1000)*0.5)*(number3 - number4);
total.setText (String.format("£%s", new java.text.DecimalFormat("##.##").format(sum)));
If you want to round up you can use this method
cantDecimal = 2;
number = 164.9835
public static double aroundUp(double number, int canDecimal) {
int cifras = (int) Math.pow(10, canDecimal);
return Math.ceil(number * cifras) / cifras;
}
return = 164.99
Extra: Ceil Method in Math.
The method ceil gives the smallest integer that is greater than or equal to the argument.

Float random with value from "1.3000 to 1.4000" is possible?

Its possible to make float random from range 1.3000 to 1.4000? That give me numbers like 13405, 13855 etc.
I know double is more flexible with range floating point, but i cant use it.
So i create something like:
float highmax = 0.6500f;
float highlow = 0.7000f;
float generatedFloatHigh = highmax + new Random().nextFloat() * (highlow - highmax);
But this not work what i want.
Any suggestion? Or maybe i should look for other libraly?
You can try to get a random number(for example x) between 0 and 1000, then you can get a number from range 1.3000 to 1.4000 like this :
int x = new Random(1000).nextInt();
float result = 1.3000f + x*0.0001f;
Random generator = new Random(System.currentTimeMillis());
int n = generator.nextInt(1000);
float generatedFloatHigh = 1.3000 + n/1000;

Vertical orientation degree - Android

Anyone knows how to get smooth vertical orientation degree in Android?
I already tried OrientationEventListener as shown below but it's very noisy. already tried all rates, Normal, Delay, Game and Fastest, all shown the same result.
myOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int arg0) {
orientaion = arg0;
Log.i("orientaion", "orientaion:" + orientaion);
}
};
So there are two things going on that can affect what you need.
Sensor delay. Android provides four different sensor delay modes: SENSOR_DELAY_UI, SENSOR_DELAY_NORMAL, SENSOR_DELAY_GAME, and SENSOR_DELAY_FASTEST, where SENSOR_DELAY_UI has the longest interval between two data points and SENSOR_DELAY_FASTEST has the shortest. The shorter the interval the higher data sampling rate (number of samples per second). Higher sampling rate gives you more "responsive" data, but comes with greater noise, while lower sampling rate gives you more "laggy" data, but more smooth.
Noise filtering. With the above in mind, you need to decide which route you want to take. Does your application need fast response? If it does, you probably want to choose a higher sampling rate. Does your application need smooth data? I guess this is obviously YES given the context of the question, which means you need noise filtering. For sensor data, noise is mostly high frequency in nature (noise value oscillates very fast with time). So a low pass filter (LPF) is generally adequate.
A simple way to implement LPF is exponential smoothing. To integrate with your code:
int orientation = <init value>;
float update_rate = <value between 0 to 1>;
myOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int arg0) {
orientation = (int)(orientation * (1f - update_rate) + arg0 * update_rate);
Log.i("orientation", "orientation:" + orientation);
}
};
Larger update_value means the resulting data is less smooth, which should be intuitive: if update_value == 1f, it falls back to your original code. Another note about update_value is it depends on the time interval between updates (related to sensor delay modes). You probably can tune this value to find one works for you, but if you want to know exactly how it works, check the alpha value definition under Electronic low-pass filters -> Discrete-time realization.
I had a similar problem showing an artificial horizon on my device. The low pass filter (LPF) solved this issue.
However you need to consider when you use the orientation angle in degrees and apply the LPF on it blindly, the result is faulty when the device is in portrait mode and turned from left to ride or opposite. The reason for this is the shift between 359 and 0 degree. Therefore I recommend to convert the degree into radians and apply the LPF on the sin and cos values of the orientation angle.
Further I recommend to use a dynamic alpha or update rate for the LPF. A static value for the alpha might be perfect on your device but not on any other.
The following class filters based on radians and uses a dynamic alpha as described above:
import static java.lang.Math.*;
Filter {
private static final float TIME_CONSTANT = .297f;
private static final float NANOS = 1000000000.0f;
private static final int MAX = 360;
private double alpha;
private float timestamp;
private float timestampOld;
private int count;
private int values[];
Filter() {
timestamp = System.nanoTime();
timestampOld = System.nanoTime();
values = new int[0];
}
int filter(int input) {
//there is no need to filter if we have only one
if(values.length == 0) {
values = new int[] {0, input};
return input;
}
//filter based on last element from array and input
int filtered = filter(values[1], input);
//new array based on previous result and filter
values = new int[] {values[1], filtered};
return filtered;
}
private int filter(int previous, int current) {
calculateAlpha();
//convert to radians
double radPrev = toRadians(previous);
double radCurrent = toRadians(current);
//filter based on sin & cos
double sumSin = filter(sin(radPrev), sin(radCurrent));
double sumCos = filter(cos(radPrev), cos(radCurrent));
//calculate result angle
double radRes = atan2(sumSin, sumCos);
//convert radians to degree, round it and normalize (modulo of 360)
long round = round(toDegrees(radRes));
return (int) ((MAX + round) % MAX);
}
//dynamic alpha
private void calculateAlpha() {
timestamp = System.nanoTime();
float diff = timestamp - timestampOld;
double dt = 1 / (count / (diff / NANOS));
count++;
alpha = dt/(TIME_CONSTANT + dt);
}
private double filter(double previous, double current) {
return (previous + alpha * (current - previous));
}
}
For further readings see this discussion.

Does Android ColorMatrix setSaturation() support values greater than one?

Looking at the Android docs, the ColorMatrix setSaturation() method says:
Set the matrix to affect the saturation of colors. A value of 0 maps the color to gray-scale. 1 is identity.
I'm trying to boost the saturation (in terms of HSL/HSV) to get more intense colors, so I passed in 1.6 and it seems to work. I've run into device-specific issues with Android layout shadowRadius values less than 1, so is there a danger of those types of issues with this parameter and exceeding the specified range?
The range for the saturation is indeed between 0 and 1. But lets take a look at the code for the setSaturation() method. (Android is open source):
public void setSaturation(float sat) {
reset();
float[] m = mArray;
final float invSat = 1 - sat; //<---------invSat will be negative if sat bigger than 1
final float R = 0.213f * invSat;
final float G = 0.715f * invSat;
final float B = 0.072f * invSat;
m[0] = R + sat; m[1] = G; m[2] = B;
m[5] = R; m[6] = G + sat; m[7] = B;
m[10] = R; m[11] = G; m[12] = B + sat;
}
The part of the code that we care about is pointed out. As you can see,The method will take your input and subtract it from 1. If you input a value greater than 1, this will result in a negative value for the invSat, and as you can see it may cause bigger problems as well.

Operation from float to BigDecimal in Java

I'm doing a math operation beetwen hours, but I've a problem with the float (the java virtual machine approximate is not perfect). So, I decided to convert this operation in BigDecimal...but I've some problems with results..
This is the original code:
public float ConvertTo100(float input)
{
float output = 0.0f;
int hh;
float mm;
hh = (int)input;
mm = input - hh;
output = hh + ((input - hh)/60) * 100;
return output;
}
This is my convertion, but doesn't works:
public float ConvertTo100(float input)
{
BigDecimal inputBD = new BigDecimal(Float.toString(input));
String inpString = String.valueOf(input);
String[] inpsplit = inpString.split("\\.");
BigDecimal hh = new BigDecimal(Float.toString(Integer.parseInt(inpsplit[0])));
BigDecimal output = hh.add((inputBD.subtract(hh).divide(BigDecimal.valueOf(60))).multiply(BigDecimal.valueOf(1000)));
return Float.parseFloat(String.valueOf(output));
}
Where is the problem?? Thank you so much!!! :)
Division by 60 cannot be done exactly in decimal for many inputs. To continue using BigDecimal, you will need to pick a scale and rounding mode for the division. Here's one way of doing it, but read the BigDecimal documentation to see all the options.
BigDecimal output = hh.add((inputBD.subtract(hh).divide(
BigDecimal.valueOf(60), 10, BigDecimal.ROUND_HALF_EVEN))
.multiply(BigDecimal.valueOf(1000)));
However, the main point of using BigDecimal is to get exact representation of decimal fractions. You are not getting that benefit, but are getting the messy code that results from doing arithmetic using method calls instead of infix operators. Unless you need a specific rounding mode, or some finite precision greater than 16.9 significant digits, you would be much better off using double.

Categories

Resources