如何在android中测量环境温度

Posted

技术标签:

【中文标题】如何在android中测量环境温度【英文标题】:how to measure ambient temperature in android 【发布时间】:2012-08-16 12:28:40 【问题描述】:

我想在安卓设备上测量环境温度。但我的设备不包括温度计传感器。 我该如何测量它? 谢谢。

【问题讨论】:

***.com/questions/11987134/… 【参考方案1】:

这是一个如何获取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.
    

您可以从以下网址下载完整的示例: https://github.com/Jorgesys/Android_Ambient_Temperature

【讨论】:

你不知道有没有支持这个的手机?还是仅适用于特殊设备? 只有部分设备有温度传感器。您可以通过 Sensor mTemperature= mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);如果 mTemperature == null 设备没有温度传感器。【参考方案2】:

这是无法做到的。温度传感器即使存在电池温度和cpu温度。

编辑:正如 swayam 指出的那样,API 14 中添加了环境温度传感器,但 gingerbread compatibility document 明确表示不包括温度测量

设备实现可以但不应包含温度计(即 温度传感器。)如果设备实现确实包括 温度计,它必须测量设备 CPU 的温度。它 不得测量任何其他温度。 (请注意,这种传感器类型是 在 Android 2.3 API 中已弃用。)

但大多数手机只包含 cpu 温度测量传感器Sensor.TYPE_TEMPERATURE,已弃用。 所以这并不能给出准确的温度。你应该使用Sensor.TYPE_AMBIENT_TEMPERATURE,我认为很多手机都没有。

【讨论】:

但我有一个从 googleplay 下载的应用程序。它测量。怎么样? 可能只是联系了一些服务器,比如 accuweather 并根据您的位置返回城市温度 @nandeesh:如果我错了,请原谅我,但环境温度可以从 API 14 及更高版本测量。他们在 ICS 中介绍了这一点。请看这里:developer.android.com/guide/topics/sensors/… @nandeesh 你能告诉你如何找到当前的 cpu 级别值吗? 今天这个问题的状态如何?即使手机没有温度计传感器,有没有办法让手机周围的环境温度?我已经阅读了很多这方面的内容,有人说可以结合电池/CPU温度来获得它吗?有人说这是不可能的。真正的真相是什么?专家意见是什么【参考方案3】:

试试这个代码:

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) 
 

此外,您还可以在此处查看 SensorManager 的文档:http://developer.android.com/reference/android/hardware/SensorManager.html

更多关于传感器的信息:

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

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

【讨论】:

是的,如果你想测量温度,你的设备需要有温度计,对吧? 是的,对,但我听说有一些算法。他们可以使用电池温度来创造环境温度 原谅我的无知,但我猜你的电池会根据你手机的使用情况而变热。如果您长时间使用手机并访问网络和运行消耗大量电池的应用程序,那么您的电池可能会变热。现在,电池的温度上升,但房间的温度将保持不变。那么,如果你试图通过电池温度来确定房间的温度,你不认为你会得到比实际值高很多的环境温度吗? 您需要使用 Sensor.TYPE_AMBIENT_TEMPERATURE 而不是 Sensor.TYPE_TEMPERATURE 已弃用 @Furkan :帮助不是问题。 :)【参考方案4】:

Android 5.0

使用 CPU 和电池获取环境温度

***首先获得平均运行热量

    查找实际温度并删除冷设备 CPU 温度

    例如。 40°C - 29°C = 11°C 运行温度

    获取电池温度并与 CPU 温度进行比较

    电池 > cpu = 充电/保持/不使用 电池

    计算 30 分钟内的最低读数

    计算比较热差

    使用 = 平均温度 - 3°C 不使用 = 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);
    

我已经知道不建议绕过像这样的受限文件夹,但是 CPU 温度总是以固定度数返回,我需要完整的小数位 - 所以我使用了这种相当老套的方法来绕过使用 RandomAccessFile 的限制

请不要评论说 - 这是不可能的,我知道使用这种技术检测周围的温度是不完全可能的,但是经过很多天 - 我已经设法让它达到 2°C 的精度

我的平均热量比实际温度高 11°C

我的用法,

getAmbientTemperature(11,30);

11 是平均温度

30 是下一次重置时间(最小检查周期)

注意事项, • 检查屏幕正常运行时间有助于计算热量随时间的变化 • 检查加速度计有助于建议用户将手机放下以冷却 CPU 和电池以提高准确性。 • 需要为权限添加 Android 5.0+ 支持

我的设备上的精度为 2°C

【讨论】:

如果你开始挖掘像"sys/class/thermal/thermal_zone1/temp" 这样的绝对文件路径,那是很危险的。你会遇到崩溃。最好找一个合法的 API。

以上是关于如何在android中测量环境温度的主要内容,如果未能解决你的问题,请参考以下文章

如何设计高精度温度传感电路

修复Android中的环境温度

如何利用PN结来测量温度?

通过测量我们周围啥的温度就可以知道当地的气温

如何拟合温度/热曲线的数据?

热视觉2:使用Python和OpenCV从图像中测量温度