41

Unity3D研究院之实时获取手机电流、电压、计算功率发热(一百一十八)

 3 years ago
source link: https://www.xuanyusong.com/archives/4753
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > Unity3D研究院之实时获取手机电流、电压、计算功率发热(一百一十八)

Unity3D研究院之实时获取手机电流、电压、计算功率发热(一百一十八)

灵感来自Android的BatteryManager,可以实时获取到手机的电流。因为电压是恒定的,这样就能算出功率来,十分有助于统计手机发热问题。

BatteryManager并没有提供获取手机毫安的方法, 只提供了手机剩余毫安的方法,以及手机当前电量百分比。 这样虽然可以近似还原手机总毫安,但是还是有点偏差。还有一种方法是用com.android.internal.os.PowerProfile 来取手机电池总毫安时,但是在C#代码中写起来过于复杂,后续可以移植在java代码中。

测试的时候有点需要注意,不能插USB因为充电状态获取的电流是负数。

直接上代码。测试机是小米10 Pro

using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
    float e = 0;
    private void OnGUI()
        GUILayout.Label(string.Format($"<size=80>电池总容量{Power.capacity}毫安,电压{Power.voltage}伏</size>"));
        GUILayout.Label(string.Format($"<size=80>实时电流{e}毫安,实时功率{(int)(e * Power.voltage)},满电量能玩{((Power.capacity /e).ToString("f2"))}小时</size>"));
    float t = 0f;
    private void Update()
        if(Time.time - t > 1f)
            t = Time.time;
            e = Power.electricity;
public class Power
    static public float electricity
#if UNITY_ANDROID
            //获取电流(微安),避免频繁获取,取一次大概2毫秒
            float electricity = (float)manager.Call<int>("getIntProperty", PARAM_BATTERY);
            //小于1W就认为它的单位是毫安,否则认为是微安
            return ToMA(electricity);
#else
            return -1f;
#endif
    //获取电压 伏
    static public float voltage { get; private set; }
    //获取电池总容量 毫安
    static public int capacity { get; private set; }
    //获取实时电流参数
    static object[] PARAM_BATTERY = new object[] { 2 }; //BatteryManager.BATTERY_PROPERTY_CURRENT_NOW)
    static AndroidJavaObject manager;
    static Power()
#if UNITY_ANDROID
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        manager = currActivity.Call<AndroidJavaObject>("getSystemService", new object[] { "batterymanager" });
        capacity = (int)(ToMA((float)manager.Call<int>("getIntProperty", new object[] { 1 })) / ((float)manager.Call<int>("getIntProperty", new object[] { 4 })/100f));   //BATTERY_PROPERTY_CHARGE_COUNTER 1 BATTERY_PROPERTY_CAPACITY 4
        AndroidJavaObject receive = currActivity.Call<AndroidJavaObject>("registerReceiver", new object[] { null,new AndroidJavaObject("android.content.IntentFilter", new object[] { "android.intent.action.BATTERY_CHANGED" }) });
        if (receive != null)
            voltage = (float)receive.Call<int>("getIntExtra", new object[] { "voltage",0 })/1000f; //BatteryManager.EXTRA_VOLTAGE
#endif
    static float ToMA(float maOrua)
        return maOrua < 10000 ? maOrua : maOrua / 1000f;

Unity3D研究院之实时获取手机电流、电压、计算功率发热(一百一十八) - 雨松MOMO程序研究院 - 1

Unity3D研究院之实时获取手机电流、电压、计算功率发热(一百一十八) - 雨松MOMO程序研究院 - 2
通过这两个例子就能看出来,具体性能以及发热的比例了。欢迎有相关经验的小伙伴留言一起讨论。

作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity3D研究院之实时获取手机电流、电压、计算功率发热(一百一十八)》有 1 条评论

留下一个回复 取消回复

你的email不会被公开。

评论

姓名 *

电子邮件 *

站点


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK