1. 程式人生 > >Unity&Android之二:獲取手機電量資訊、網路狀況

Unity&Android之二:獲取手機電量資訊、網路狀況

Unity&Android之二:獲取手機電量資訊、網路狀況

遊戲中經常會在UI顯示電量以及網路狀況

手機電量包括:
1、當前正在充電還是放電
2、當前電量值

網路包括:
1、如果是WIFI,WIFI訊號強度
2、如果是流量,訊號強度等資料

例如王者榮耀中右上角所示
這裡寫圖片描述

那麼接下來就介紹一下如何實現獲取手機電量資訊以及網路狀況等資料。

1、開啟Eclipse建一個安卓庫工程,注意是庫工程

這裡寫圖片描述

這裡注意一下包名

這裡寫圖片描述

這裡寫圖片描述

Icon顯示方式選擇,預設即可

這裡寫圖片描述

選擇一個空的activity

這裡寫圖片描述

安卓Activity名稱,預設即可,Finish

這裡寫圖片描述

建立完之後,就會得到這樣一個工程

這裡寫圖片描述

至於目錄結構,請自行補充相關知識

工程建立好,此時安卓還無法與Unity進行互動,需要為工程匯入一個Unity提供的classes.jar,該檔案在Unity的安裝目錄下

這裡寫圖片描述

將該jar檔案匯入到工程目錄下的libs資料夾中,滑鼠選中工程根目錄

這裡寫圖片描述

準備工作完成之後,就可以開始編寫程式碼了。

修改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檔案
這裡寫圖片描述

點選Add按鈕新增許可權

這裡寫圖片描述

選中最後一項Uses Permission

新增Name為android.permission.ACCESS_WIFI_STATE的許可權

這裡寫圖片描述

記得儲存該檔案!

許可權弄完之後即可到處jar包到Unity工程中了。

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

jar匯出後,就可以建立一個Unity工程,進行測試了。

建立一個Plugins/Android的資料夾,該資料夾用來 存放安卓外掛的。

將Android工程中的Libs、Res、AndroidMainFest.xml檔案拷貝過來,如下:
這裡寫圖片描述

接下來編寫測試程式碼:

在場景中建立一個Button(用來點選從安卓那邊獲取資料)和兩個text(分別用來顯示電量資料和wifi資料),並建立一個test指令碼

這裡寫圖片描述

指令碼程式碼如下:

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,

這裡寫圖片描述

可以build成apk了。

測試截圖:

這裡寫圖片描述

從圖中可以看出
當前手機正在充電,並且電量為60,至於圖中的61屬於浮點型別資料的運算帶來的精度問題,不過這點問題在應用中不足為慮。
而wifi狀況則是,四格訊號,都是正常的。

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

以上知識分享,步驟詳細,如有錯誤,歡迎指出,共同學習,共同進步