欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity&Android之二:获取手机电量信息、网络状况

程序员文章站 2024-03-25 10:05:58
...

Unity&Android之二:获取手机电量信息、网络状况

游戏中经常会在UI显示电量以及网络状况

手机电量包括:
1、当前正在充电还是放电
2、当前电量值

网络包括:
1、如果是WIFI,WIFI信号强度
2、如果是流量,信号强度等数据

例如王者荣耀中右上角所示
Unity&Android之二:获取手机电量信息、网络状况

那么接下来就介绍一下如何实现获取手机电量信息以及网络状况等数据。

1、打开Eclipse建一个安卓库工程,注意是库工程

Unity&Android之二:获取手机电量信息、网络状况

这里注意一下包名

Unity&Android之二:获取手机电量信息、网络状况

Unity&Android之二:获取手机电量信息、网络状况

Icon显示方式选择,默认即可

Unity&Android之二:获取手机电量信息、网络状况

选择一个空的activity

Unity&Android之二:获取手机电量信息、网络状况

安卓Activity名称,默认即可,Finish

Unity&Android之二:获取手机电量信息、网络状况

创建完之后,就会得到这样一个工程

Unity&Android之二:获取手机电量信息、网络状况

至于目录结构,请自行补充相关知识

工程创建好,此时安卓还无法与Unity进行交互,需要为工程导入一个Unity提供的classes.jar,该文件在Unity的安装目录下

Unity&Android之二:获取手机电量信息、网络状况

将该jar文件导入到工程目录下的libs文件夹中,鼠标选中工程根目录

Unity&Android之二:获取手机电量信息、网络状况

准备工作完成之后,就可以开始编写代码了。

修改MainActivity.java类的父类为UnityPlayerActivity

该类需要import相关的包

import com.unity3d.player.UnityPlayerActivity;

删除onCreate函数中的

setContentView(R.layout.activity_main);

至此,MainActivity.java文件代码如下:

package com.unityplugin.phonepower;

import com.unity3d.player.UnityPlayerActivity;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends UnityPlayerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

接下来编写函数以供Unity调用

完整代码如下:

package com.unityplugin.phonepower;

import com.unity3d.player.UnityPlayerActivity;

import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;

public class MainActivity extends UnityPlayerActivity {

    private static Context instance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        instance = getApplication();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    //获取手机当前电量、总电量(默认其实都是100)、当前状态(充电还是放电)
    //其余数据例如电压、电池温度用的较少
    public String MonitorBatteryState()
    {
        IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent intent = instance.registerReceiver(null, iFilter);
        int rawLevel = intent.getIntExtra("level", 0);      //获得当前电量
        int scale = intent.getIntExtra("scale", 0);         //获得总电量
        int status = intent.getIntExtra("status", 0);       //电池充电状态
        int health = intent.getIntExtra("voltage", 0);      //电池健康状况
        int batteryV = intent.getIntExtra("voltage", 0);    //电池电压(mv)
        int temperature = intent.getIntExtra("temperature", 0); //电池温度(数值)
        double t = temperature / 10.0;  //电池摄氏温度,默认获取的非摄氏温度值,需做一下运算转换
        String targetStr = "";
        int level = -1;
        if(rawLevel > 0 && scale > 0)
        {
            level = (rawLevel * 100) / scale;
            targetStr = level + "|" + scale + "|" + status;
        }
        return targetStr;
    }

    //获取Wifi信号强度
    @SuppressWarnings("deprecation")
    private String ObtainWifiInfo()
    {
        String result = "";
        WifiManager wifiManager = (WifiManager)getApplication().getSystemService(WIFI_SERVICE);
        WifiInfo info = wifiManager.getConnectionInfo();
        if(info.getBSSID() != null)
        {
            //链接信号强度
            int strength = WifiManager.calculateSignalLevel(info.getRssi(), 5);
            //链接速度
            int speed = info.getLinkSpeed();
            //链接速度单位
            String units = WifiInfo.LINK_SPEED_UNITS;
            //Wifi源名称
            String ssid = info.getSSID();
            int ip = info.getIpAddress();
            String mac = info.getMacAddress();
            result = strength + "|" + IntToIp(ip) + "|" + mac + "|" + ssid;
        }
        return result;
    }

    private String IntToIp(int paramInt)
    {
        return (paramInt & 0xFF) + "." + (0xFF & paramInt >> 8) + "." + (0xFF & paramInt >> 16) + "." + (0xFF & paramInt >> 24);
    }
}

代码编写完之后,还有一件重要的事情,那就是手机权限。
访问手机电量,不需要权限,不过WIFI状况需要添加一个权限。

如何添加权限

双击AndroidManifest.xml文件
Unity&Android之二:获取手机电量信息、网络状况

点击Add按钮添加权限

Unity&Android之二:获取手机电量信息、网络状况

选中最后一项Uses Permission

添加Name为android.permission.ACCESS_WIFI_STATE的权限

Unity&Android之二:获取手机电量信息、网络状况

记得保存该文件!

权限弄完之后即可到处jar包到Unity工程中了。

Unity&Android之二:获取手机电量信息、网络状况

Unity&Android之二:获取手机电量信息、网络状况

Unity&Android之二:获取手机电量信息、网络状况

jar导出后,就可以创建一个Unity工程,进行测试了。

创建一个Plugins/Android的文件夹,该文件夹用来 存放安卓插件的。

将Android工程中的Libs、Res、AndroidMainFest.xml文件拷贝过来,如下:
Unity&Android之二:获取手机电量信息、网络状况

接下来编写测试代码:

在场景中创建一个Button(用来点击从安卓那边获取数据)和两个text(分别用来显示电量数据和wifi数据),并创建一个test脚本

Unity&Android之二:获取手机电量信息、网络状况

脚本代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour 
{
    public Button button;
    public Text phonePowerText;
    public Text wifiText;

    private string batteryData;
    private string wifiData;

    void Awake()
    {
        button.onClick.AddListener(OnButtonClicked);
    }

    private void OnButtonClicked()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        batteryData = jo.Call<string>("MonitorBatteryState");
        wifiData = jo.Call<string>("ObtainWifiInfo");
        OnBatteryDataBack(batteryData);
        OnWifiDataBack(wifiData);
    }

    //安卓那边将数据以“|”进行分割,所以这边以"|"来分割数据
    private void OnBatteryDataBack(string data)
    {
        phonePowerText.text = "";
        string[] args = data.Split('|');
        if (args[2] == "2")
        {
            phonePowerText.text += "电池充电中\n";
        }
        else
        {
            phonePowerText.text += "电池放电中\n";
        }
        int curPower = int.Parse(args[0]);
        float power = float.Parse(args[1]);
        float percent = curPower / power;
        phonePowerText.text += " cur power:" + curPower;
        phonePowerText.text += "  all power:" + power;
        phonePowerText.text += " 电量比例:" + (Mathf.CeilToInt(percent * 100) + "%").ToString();
    }

    private void OnWifiDataBack(string data)
    {
        wifiText.text = "";
        wifiText.text += wifiData;
        string[] args = wifiData.Split('|');
        int wifiLevel = int.Parse(args[0]);
        wifiText.text += "Wifi信号格数:" + wifiLevel.ToString() + "\n";
        string ip = "IP:" + args[1] + "\n";
        string mac = "MAC:" + args[2] + "\n";
        string ssid = "Wifi Name:" + args[3] + "\n";
        wifiText.text += ip;
        wifiText.text += mac;
        wifiText.text += ssid;
    }
}

记得将工程平台切换成Android

最后设置PlayerSettings,

Unity&Android之二:获取手机电量信息、网络状况

可以build成apk了。

测试截图:

Unity&Android之二:获取手机电量信息、网络状况

从图中可以看出
当前手机正在充电,并且电量为60,至于图中的61属于浮点类型数据的运算带来的精度问题,不过这点问题在应用中不足为虑。
而wifi状况则是,四格信号,都是正常的。

抱歉,IP地址被我打码了。

以上知识分享,步骤详细,如有错误,欢迎指出,共同学习,共同进步