9

I want to measure ambient temperature on android device. but my device doesn t include thermometer sensor. How can I measure it? Thanks.

Furkan
  • 428
  • 3
  • 5
  • 19

4 Answers4

12

this is a basic example of how to get the Ambient Temperature in Android:

import android.support.v7.app.AppCompatActivity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private TextView temperaturelabel;
    private SensorManager mSensorManager;
    private Sensor mTemperature;
    private final static String NOT_SUPPORTED_MESSAGE = "Sorry, sensor not available for this device.";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        temperaturelabel = (TextView) findViewById(R.id.myTemp);
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.ICE_CREAM_SANDWICH){
            mTemperature= mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE); // requires API level 14.
        }
        if (mTemperature == null) {             
            temperaturelabel.setText(NOT_SUPPORTED_MESSAGE);
        }       
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, mTemperature, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {                 
        super.onPause();
        mSensorManager.unregisterListener(this);
    }


    @Override
    public void onSensorChanged(SensorEvent event) {
        float ambient_temperature = event.values[0];
        temperaturelabel.setText("Ambient Temperature:\n " + String.valueOf(ambient_temperature) + getResources().getString(R.string.celsius));     
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
    }
}

you can download the complete example from : https://github.com/Jorgesys/Android_Ambient_Temperature

Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • Do you happen to know if there are phones that support this? or is this just for special devices? – raddevus Feb 14 '20 at 21:37
  • Just some devices have temperature sensor.You can check by Sensor mTemperature= mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE); if mTemperature == null the device doesn´t have temperature sensor. – Jorgesys Feb 14 '20 at 22:42
3

This cannot be done. The temperature sensor even if exists if for the battery temperature and cpu temperature.

Edit: As swayam pointed out there is Ambient Temperature sensor added in API 14 but gingerbread compatibility document explicitly says not to include temperature measurement

Device implementations MAY but SHOULD NOT include a thermometer (i.e. temperature sensor.) If a device implementation does include a thermometer, it MUST measure the temperature of the device CPU. It MUST NOT measure any other temperature. (Note that this sensor type is deprecated in the Android 2.3 APIs.)

But most phones only include cpu temperature measurement sensor Sensor.TYPE_TEMPERATURE which is deprecated. So this does not give accurate temperature. You should use Sensor.TYPE_AMBIENT_TEMPERATURE which I dont think many phones have.

nandeesh
  • 24,740
  • 6
  • 69
  • 79
  • 1
    but I have a application I downloaded from googleplay. it measures. how? – Furkan Aug 16 '12 at 12:32
  • maybe it is just contacting some server like accuweather and returning the city temperature based on your location – nandeesh Aug 16 '12 at 12:34
  • @nandeesh : Forgive me if I am wrong but Ambient Temperature can be measured from API 14 and upwards. They introduced this in the ICS. Please have a look here : http://developer.android.com/guide/topics/sensors/sensors_environment.html – Swayam Aug 16 '12 at 12:38
  • @nandeesh can u pls tell how u find current cpu level values ? – user3233280 Nov 24 '14 at 18:21
  • What is the status on this issue today? Is there a way to get the environment temp around the phone even if the phone does not have a thermometer sensor? I have read a lot on this and some say it is possible to get it combining battery/CPU temp? And some say it is not possible. What is the actual truth? What is the expert opinion – quant Feb 10 '19 at 10:31
2

Have a go at this code:

public class SensorActivity extends Activity, implements SensorEventListener {
 private final SensorManager mSensorManager;
 private final Sensor mTemp;

 public SensorActivity() {
     mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
     mtemp = mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE);
 }

 protected void onResume() {
     super.onResume();
     mSensorManager.registerListener(this, mTemp, SensorManager.SENSOR_DELAY_NORMAL);
 }

 protected void onPause() {
     super.onPause();
     mSensorManager.unregisterListener(this);
 }

 public void onAccuracyChanged(Sensor sensor, int accuracy) {
 }

 public void onSensorChanged(SensorEvent event) {
 }

Plus you can go through the documentation of the SensorManager here : http://developer.android.com/reference/android/hardware/SensorManager.html

More about sensors here :

http://developer.android.com/guide/topics/sensors/sensors_overview.html

http://developer.android.com/guide/topics/sensors/sensors_environment.html

Swayam
  • 16,294
  • 14
  • 64
  • 102
  • Yes, you device needs to have a thermometer if you want to measure the temperature, right ? – Swayam Aug 16 '12 at 12:39
  • yes, right but I have heard there are some algorithm . they can create ambient temperature with using battery temperature – Furkan Aug 16 '12 at 12:43
  • Forgive my ignorance, but I guess your battery would heat up according to the usage of your phone. If you are using your phone for a long time and accessing the web and running app that consume a lot of battery then your battery might get heated up. Now, the temperature of the battery goes up but the temperature of the room would remain the same. So, if you are trying to determine the temperature of the room by using the battery temperature, don't you think that you would get the ambient temperature much higher than the actual value ? – Swayam Aug 16 '12 at 12:49
  • you need to use Sensor.TYPE_AMBIENT_TEMPERATURE and not Sensor.TYPE_TEMPERATURE which is deprecated – nandeesh Aug 16 '12 at 12:54
  • @Furkan : Not a problem to help. :) – Swayam Aug 16 '12 at 12:55
0

Android 5.0

Using CPU & Battery to gain Ambient Temperature

  • ***Get Average Running Heat First

    1. Find real temperature & remove Cold Device CPU Temperature

      • Eg. 40°C - 29°C = 11°C Running Temperature
    2. Get Battery Temperature & Compare with CPU Temperature

      • battery > cpu = Charging/Holding/No Usage
      • battery < cpu = Intensive CPU Task / Usage
    3. Calculate Lowest Reading Over 30 Minutes

    4. Calculate Comparison Heat Difference

      • Using = averageTemp - 3°C
      • No Usage = averageTemp

`

// EXAMPLE ONLY - RESET HIGHEST AT 500°C
    public Double closestTemperature = 500.0;
    public Long resetTime = 0L;
    public String getAmbientTemperature(int averageRunningTemp, int period)
    {
    // CHECK MINUTES PASSED ( STOP CONSTANT LOW VALUE )  
        Boolean passed30 = ((System.currentTimeMillis() - resetTime) > ((1000 * 60)*period));
        if (passed30)
        {
            resetTime = System.currentTimeMillis();
            closestTemperature = 500.0;
        }

    // FORMAT DECIMALS TO 00.0°C
        DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
        dfs.setDecimalSeparator('.');
        DecimalFormat decimalFormat = new DecimalFormat("##.0", dfs);

    // READ CPU & BATTERY
        try
        {
       // BYPASS ANDROID RESTRICTIONS ON THERMAL ZONE FILES & READ CPU THERMAL

            RandomAccessFile restrictedFile = new RandomAccessFile("sys/class/thermal/thermal_zone1/temp", "r");
            Double cpuTemp = (Double.parseDouble(restrictedFile.readLine()) / 1000);

        // RUN BATTERY INTENT
            Intent batIntent = this.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));    
       // GET DATA FROM INTENT WITH BATTERY
            Double batTemp = (double) batIntent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) / 10;

       // CHECK IF DATA EXISTS
            if (cpuTemp != null)
            {
           // CPU FILE OK - CHECK LOWEST TEMP
                if (cpuTemp - averageRunningTemp < closestTemperature)
                    closestTemperature = cpuTemp - averageRunningTemp;
            }
            else if (batTemp != null)
            {
             // BAT OK - CHECK LOWEST TEMP
                if (batTemp - averageRunningTemp < closestTemperature)
                    closestTemperature = batTemp - averageRunningTemp;
            }
            else
            {
            // NO CPU OR BATTERY TEMP FOUND - RETURN 0°C
                closestTemperature = 0.0;
            }
        }
        catch (Exception e)
        {
            // NO CPU OR BATTERY TEMP FOUND - RETURN 0°C
            closestTemperature = 0.0;
        }
     // FORMAT & RETURN
        return decimalFormat.format(closestTemperature);
    }

I already know that bypassing restricted folders like this is not recommended, however the CPU temperature is always returned as a solid Degree, i need the full decimal places - So I've used this rather hacky approach to bypass restrictions using RandomAccessFile

Please do not comment saying - It's not possible, i know it isn't fully possible to detect the surrounding temperature using this technique, however after many days - I've managed to get it to 2°C Accuracy

My Average Heat was 11°C higher than the real temperature

Making my Usage,

getAmbientTemperature(11,30);

11 being Average Temperature

30 being Next Reset Time ( Period of minimum check )

NOTES, • Checking Screen UpTime can help to calculate heat changes over time
• Checking Accelerometer can help to suggest the user Places the phone down to Cool the CPU & Battery for an increased accuracy.
• Android 5.0+ Support needs to be added for Permissions

2°C Accuracy on my device

Empire of E
  • 588
  • 6
  • 12
  • If you start to dig into absolute file paths like `"sys/class/thermal/thermal_zone1/temp"` that's dangerous. You gonna run into crashes. It's better to seek a legitimate API. – Csaba Toth Sep 25 '20 at 20:22
  • You cannot guess the room's temperature based on a comparison between battery temp and CPU temp. – yuroyami Jul 13 '22 at 18:56