如何在安卓设备中测量环境温度?

9

我想在安卓设备上测量环境温度,但我的设备没有温度计传感器。我该如何测量?谢谢。


https://dev59.com/jmfWa4cB1Zd3GeqPgFhx#29285300 - Empire of E
4个回答

12

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


你知道是否有手机支持这个吗?还是只适用于特殊设备? - raddevus
只有一些设备拥有温度传感器。您可以通过Sensor mTemperature= mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE); 进行检查,如果mTemperature == null,则该设备没有温度传感器。 - Jorgesys

3
这是不可能的。即使存在温度传感器,也只能测量电池和CPU温度。
编辑:正如swayam指出的那样,API 14中添加了环境温度传感器,但姜饼兼容性文档明确表示不包括温度测量。

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

但大多数手机只包括cpu温度测量传感器Sensor.TYPE_TEMPERATURE,这已经被弃用了。因此,这不能提供准确的温度。您应该使用Sensor.TYPE_AMBIENT_TEMPERATURE,但我认为很少有手机有这个传感器。

1
但我有一个从Google Play下载的应用程序。它测量什么? - Furkan
也许只是通过联系像AccuWeather这样的服务器,并根据您的位置返回城市温度。 - nandeesh
@nandeesh:如果我错了,请原谅我,但是环境温度可以从API 14及以上版本进行测量。他们在ICS中引入了这个功能。请看这里:http://developer.android.com/guide/topics/sensors/sensors_environment.html - Swayam
@nandeesh,请问您是如何查找当前CPU水平值的? - user3233280
今天这个问题的状态如何? 即使手机没有温度计传感器,有没有办法获取手机周围的环境温度?我已经阅读了很多相关资料,有些人说可以通过结合电池/CPU温度来获取,而有些人则认为不可能。实际上是什么情况?专家意见如何? - quant

2

试着运行这段代码:

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


是的,如果你想测量温度,你的设备需要有一个温度计,对吧? - Swayam
是的,没错。但我听说有一些算法可以利用电池温度来创造环境温度。 - Furkan
请原谅我的无知,但我猜您的电池会根据手机的使用情况而发热。如果您长时间使用手机并访问消耗大量电池的网络和应用程序,则电池可能会发热。现在,电池的温度会上升,但房间的温度仍然保持不变。因此,如果您尝试通过使用电池温度来确定房间的温度,您不认为您会得到比实际值高得多的环境温度吗? - Swayam
你需要使用 Sensor.TYPE_AMBIENT_TEMPERATURE 而不是已被弃用的 Sensor.TYPE_TEMPERATURE。 - nandeesh
@Furkan:帮忙不是问题。 :) - Swayam

0

Android 5.0

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

  • ***首先获取平均运行热量

    1. 找到实际温度并去除冷设备CPU温度

      • 例如:40°C - 29°C = 11°C 运行温度
    2. 获取电池温度并与CPU温度进行比较

      • 电池 > CPU = 充电/保持/未使用
      • 电池 < CPU = 强制CPU任务/使用
    3. 计算30分钟内的最低读数

    4. 计算比较热差异

      • 使用 = 平均温度 - 3°C
      • 未使用 = 平均温度

`

// 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温度总是以实心度数返回,我需要完整的小数位 - 所以我使用了这种相当hacky的方法来绕过使用RandomAccessFile的限制。
请不要评论说 - 这是不可能的,我知道使用这种技术不能完全检测周围的温度,但经过多天的努力,我已经成功将其精确到2°C。
我的平均热量比实际温度高11°C
使我的使用率为,
getAmbientTemperature(11,30);
11是平均温度
30是下一个重置时间(最小检查周期)
注意事项, • 检查屏幕运行时间可以帮助计算随时间变化的热量 • 检查加速度计可以帮助建议用户将手机放下来冷却CPU和电池以获得更高的准确性。 • 需要添加Android 5.0+支持权限
在我的设备上精确到2°C。

如果你开始深入研究像 "sys/class/thermal/thermal_zone1/temp" 这样的绝对文件路径,那是很危险的。你会遇到崩溃。最好寻找一个合法的API。 - Csaba Toth
你无法仅通过比较电池温度和CPU温度来猜测房间的温度。 - yuroyami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接