Android如何獲取手機各項資訊
1、使用Build獲取架構屬性
下面我們來根據原始碼看看通過Build這個類可以得到哪些配置資訊,具體就不解釋了,從命名基本可以理解其代表的屬性。
public class Build {
//當一個版本屬性不知道時所設定的值。
public static final String UNKNOWN = "unknown";
//修訂版本列表碼
public static final String ID = getString("ro.build.id");
//顯示屏引數
public static final String DISPLAY = getString("ro.build.display.id" );
//整個產品的名稱
public static final String PRODUCT = getString("ro.product.name");
//裝置引數
public static final String DEVICE = getString("ro.product.device");
//主機板
public static final String BOARD = getString("ro.product.board");
//cpu指令集
public static final String CPU_ABI = getString("ro.product.cpu.abi" );
//cpu指令集2
public static final String CPU_ABI2 = getString("ro.product.cpu.abi2");
//硬體製造商
public static final String MANUFACTURER = getString("ro.product.manufacturer");
//系統定製商
public static final String BRAND = getString("ro.product.brand");
//版本即終端使用者可見的名稱
public static final String MODEL = getString("ro.product.model");
//系統啟動程式版本號
public static final String BOOTLOADER = getString("ro.bootloader");
//硬體名稱
public static final String HARDWARE = getString("ro.hardware");
//硬體序列號
public static final String SERIAL = getString("ro.serialno");
//build的型別
public static final String TYPE = getString("ro.build.type");
//描述build的標籤,如未簽名,debug等等。
public static final String TAGS = getString("ro.build.tags");
//唯一識別碼
public static final String FINGERPRINT = getString("ro.build.fingerprint");
public static final long TIME = getLong("ro.build.date.utc") * 1000;
public static final String USER = getString("ro.build.user");
public static final String HOST = getString("ro.build.host");
//獲取無線電韌體版本
public static String getRadioVersion() {
return SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION, null);
}
private static String getString(String property) {
return SystemProperties.get(property, UNKNOWN);
}
private static long getLong(String property) {
try {
return Long.parseLong(SystemProperties.get(property));
} catch (NumberFormatException e) {
return -1;
}
}
//各種版本字串
public static class VERSION {
public static final String INCREMENTAL = getString("ro.build.version.incremental");
public static final String RELEASE = getString("ro.build.version.release");
public static final int SDK_INT = SystemProperties.getInt(
"ro.build.version.sdk", 0);
public static final String CODENAME = getString("ro.build.version.codename");
}
//目前已知的版本程式碼的列舉類
public static class VERSION_CODES {
public static final int CUR_DEVELOPMENT = 10000;
/**
* October 2008: The original, first, version of Android. Yay!
*/
public static final int BASE = 1;
/**
* February 2009: First Android update, officially called 1.1.
*/
public static final int BASE_1_1 = 2;
/**
* May 2009: Android 1.5.
*/
public static final int CUPCAKE = 3;
/**
* September 2009: Android 1.6.
*/
public static final int DONUT = 4;
/**
* November 2009: Android 2.0
*/
public static final int ECLAIR = 5;
/**
* December 2009: Android 2.0.1
*/
public static final int ECLAIR_0_1 = 6;
/**
* January 2010: Android 2.1
*/
public static final int ECLAIR_MR1 = 7;
/**
* June 2010: Android 2.2
*/
public static final int FROYO = 8;
/**
* November 2010: Android 2.3
*/
public static final int GINGERBREAD = 9;
/**
* February 2011: Android 2.3.3.
*/
public static final int GINGERBREAD_MR1 = 10;
/**
* February 2011: Android 3.0.
*/
public static final int HONEYCOMB = 11;
/**
* May 2011: Android 3.1.
*/
public static final int HONEYCOMB_MR1 = 12;
/**
* June 2011: Android 3.2.
*/
public static final int HONEYCOMB_MR2 = 13;
/**
* October 2011: Android 4.0.
*/
public static final int ICE_CREAM_SANDWICH = 14;
/**
* December 2011: Android 4.0.3.
*/
public static final int ICE_CREAM_SANDWICH_MR1 = 15;
/**
* June 2012: Android 4.1.
*/
public static final int JELLY_BEAN = 16;
/**
* Android 4.2: Moar jelly beans!
*/
public static final int JELLY_BEAN_MR1 = 17;
/**
* Android 4.3: Jelly Bean MR2, the revenge of the beans.
*/
public static final int JELLY_BEAN_MR2 = 18;
/**
* Android 4.4: KitKat, another tasty treat.
*/
public static final int KITKAT = 19;
}
}
下面舉個例子:
/**
* 獲取裝置資訊
*
* @return
*/
private String getDeviceInfo() {
StringBuffer sb = new StringBuffer();
sb.append(主機板: + Build.BOARD);
sb.append(系統啟動程式版本號: + Build.BOOTLOADER);
sb.append(系統定製商: + Build.BRAND);
sb.append(cpu指令集: + Build.CPU_ABI);
sb.append(cpu指令集2 + Build.CPU_ABI2);
sb.append(設定引數: + Build.DEVICE);
sb.append(顯示屏引數: + Build.DISPLAY);
sb.append(www.2cto.com無線電韌體版本: + Build.getRadioVersion());
sb.append(硬體識別碼: + Build.FINGERPRINT);
sb.append(硬體名稱: + Build.HARDWARE);
sb.append(HOST: + Build.HOST);
sb.append(修訂版本列表: + Build.ID);
sb.append(硬體製造商: + Build.MANUFACTURER);
sb.append(版本: + Build.MODEL);
sb.append(硬體序列號: + Build.SERIAL);
sb.append(手機制造商: + Build.PRODUCT);
sb.append(描述Build的標籤: + Build.TAGS);
sb.append(TIME: + Build.TIME);
sb.append(builder型別: + Build.TYPE);
sb.append(USER: + Build.USER);
return sb.toString();
}
2、ActivityManager獲取記憶體資訊
在ActivityManager裡面有個getMemoryInfo函式,可以獲取到記憶體資訊。
public void getMemoryInfo(MemoryInfo outInfo) {
try {
ActivityManagerNative.getDefault().getMemoryInfo(outInfo);
} catch (RemoteException e) {
}
}
下面我們來看看MemoryInfo這個類:
public static class MemoryInfo implements Parcelable {
public long availMem;
public long totalMem;
public long threshold;
public boolean lowMemory;
public MemoryInfo() {
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(availMem);
dest.writeLong(totalMem);
dest.writeLong(threshold);
dest.writeInt(lowMemory ? 1 : 0);
dest.writeLong(hiddenAppThreshold);
dest.writeLong(secondaryServerThreshold);
dest.writeLong(visibleAppThreshold);
dest.writeLong(foregroundAppThreshold);
}
public void readFromParcel(Parcel source) {
availMem = source.readLong();
totalMem = source.readLong();
threshold = source.readLong();
lowMemory = source.readInt() != 0;
hiddenAppThreshold = source.readLong();
secondaryServerThreshold = source.readLong();
visibleAppThreshold = source.readLong();
foregroundAppThreshold = source.readLong();
}
public static final Creator<MemoryInfo> CREATOR
= new Creator<MemoryInfo>() {
public MemoryInfo createFromParcel(Parcel source) {
return new MemoryInfo(source);
}
public MemoryInfo[] newArray(int size) {
return new MemoryInfo[size];
}
};
private MemoryInfo(Parcel source) {
readFromParcel(source);
}
}
另外,需要說明的是,我們可以直接讀取系統的一個檔案來獲取記憶體資訊。這個檔案目錄為:/proc/meminfo
如下圖:
3、獲取SDCard儲存
/**
* 獲得SD卡總大小
*
* @return
*/
private String getSDTotalSize() {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return Formatter.formatFileSize(MainActivity.this, blockSize * totalBlocks);
}
/**
* 獲得sd卡剩餘容量,即可用大小
*
* @return
*/
private String getSDAvailableSize() {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return Formatter.formatFileSize(MainActivity.this, blockSize * availableBlocks);
}
/**
* 獲得機身記憶體總大小
*
* @return
*/
private String getRomTotalSize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return Formatter.formatFileSize(MainActivity.this, blockSize * totalBlocks);
}
/**
* 獲得機身可用記憶體
*
* @return
*/
private String getRomAvailableSize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return Formatter.formatFileSize(MainActivity.this, blockSize * availableBlocks);
}
另外,我們可以通過StorageManager來獲取其他的資訊,但需要注意的是有些方法需要使用反射來呼叫,因為它們是不可見的。
4、讀取CPU資訊
我們可以讀取系統目錄下/proc/cpuinfo的檔案來獲取CPU資訊。如下圖所示,事實上,我們可以檢視/proc目錄的所有檔案,來檢視各種資訊。
/proc/cmdline:顯示核心啟動的命令列。
/proc/cpuinfo:顯示系統cpu的資訊。
/proc/filesystems,顯示當前註冊了的檔案系統列表,nodev表示為虛擬檔案系統。
/proc/interrupts:顯示當前系統的中斷資訊.
/proc/ioports:被佔用的輸入/輸出地址範圍列表。
/proc/kmsg:輸出核心訊息日誌。
/proc/loadavg:監控cpu平均負載,其數值為所有核上cpu佔用的累加值,前三個分別表示最近1、5、15分鐘的平均負載,第四個表示當前執行程序數和程序總數,最後一個表示最近執行的程序id。
/proc/locks:開啟檔案上的加鎖資訊。
/proc/meminfo:顯示物理及虛擬記憶體使用情況。
/proc/misc:核心函式misc_register登記的裝置驅動程式。
/proc/modules:載入的核心模組列表。
/proc/mounts:當前系統所安裝的檔案系統資訊(包括手動安裝的)。
/proc/stat:系統簡要資訊。
/proc/uptime:分別表示系統啟動時間和系統空閒時間。
/proc/version:系統核心版本。
/proc/net:其實際掛載點是/proc/self/net,能夠顯示當前各種網路情況,例如通過tcp檔案可以檢視tcp連線數及連線情況。
/proc/sys 報告各種不同的核心引數,某些引數能在root的情況下進行修改。
/proc/devices 當前掛載的所有軟硬體裝置(字元裝置和塊裝置),包括主裝置號和裝置名稱。
/proc/asound:音效卡相關的資訊。
/proc/buddyinfo:每個記憶體區中每個order有多少塊可用,和記憶體碎片問題有關。
/proc/bus:輸入裝置資訊。
/proc/cgroups:檢視cgroups子系統資訊。
/proc/diskstats:用於顯示磁碟、分割槽和統計資訊。
/proc/execdomains:安全相關的資訊。
/proc/fb:幀緩衝裝置資訊。
/proc/iomem:記錄實體地址的分配情況。
/proc/kallsyms:核心符號表資訊。
/proc/pagetypeinfo:記憶體分頁資訊。
/proc/partitions:分割槽資訊
/proc/sched_debug:cpu排程資訊。
/proc/softirqs:軟中斷情況。
/proc/vmallocinfo:vmalloc記憶體分配資訊。
/proc/vmstat:統計虛擬記憶體資訊。
/proc/pid:顯示進城相關的所有資訊。
5、獲取電池電量資訊
獲取到電池資訊一般可以通過兩個類獲取:android.content.BroadcastReceiver類和android.os.BatteryManager類
在BroadcastReceiver的onReceive()事件,接收到的Intent.ACTION_BATTERY_CHANGED,包括下面的資訊:
“status”(int型別)…狀態,定義值是BatteryManager.BATTERY_STATUS_XXX。
“health”(int型別)…健康,定義值是BatteryManager.BATTERY_HEALTH_XXX。
“present”(boolean型別)
“level”(int型別)…電池剩餘容量
“scale”(int型別)…電池最大值。通常為100。
“icon-small”(int型別)…圖示ID。
“plugged”(int型別)…連線的電源插座,定義值是BatteryManager.BATTERY_PLUGGED_XXX。
“voltage”(int型別)…mV。
“temperature”(int型別)…溫度,0.1度單位。例如 表示197的時候,意思為19.7度。
“technology”(String型別)…電池型別,例如,Li-ion等等。
public class BatteryTestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(mBroadcastReceiver, filter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mBroadcastReceiver);
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
int status = intent.getIntExtra("status", 0);
int health = intent.getIntExtra("health", 0);
boolean present = intent.getBooleanExtra("present", false);
int level = intent.getIntExtra("level", 0);
int scale = intent.getIntExtra("scale", 0);
int icon_small = intent.getIntExtra("icon-small", 0);
int plugged = intent.getIntExtra("plugged", 0);
int voltage = intent.getIntExtra("voltage", 0);
int temperature = intent.getIntExtra("temperature", 0);
String technology = intent.getStringExtra("technology");
String statusString = "";
switch (status) {
case BatteryManager.BATTERY_STATUS_UNKNOWN:
statusString = "unknown";
break;
case BatteryManager.BATTERY_STATUS_CHARGING:
statusString = "charging";
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
statusString = "discharging";
break;
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
statusString = "not charging";
break;
case BatteryManager.BATTERY_STATUS_FULL:
statusString = "full";
break;
}
String healthString = "";
switch (health) {
case BatteryManager.BATTERY_HEALTH_UNKNOWN:
healthString = "unknown";
break;
case BatteryManager.BATTERY_HEALTH_GOOD:
healthString = "good";
break;
case BatteryManager.BATTERY_HEALTH_OVERHEAT:
healthString = "overheat";
break;
case BatteryManager.BATTERY_HEALTH_DEAD:
healthString = "dead";
break;
case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
healthString = "voltage";
break;
case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
healthString = "unspecified failure";
break;
}
String acString = "";
switch (plugged) {
case BatteryManager.BATTERY_PLUGGED_AC:
acString = "plugged ac";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
acString = "plugged usb";
break;
}
Log.v("status", statusString);
Log.v("health", healthString);
Log.v("present", String.valueOf(present));
Log.v("level", String.valueOf(level));
Log.v("scale", String.valueOf(scale));
Log.v("icon_small", String.valueOf(icon_small));
Log.v("plugged", acString);
Log.v("voltage", String.valueOf(voltage));
Log.v("temperature", String.valueOf(temperature));
Log.v("technology", technology);
}
}
};
}
應用程式為了取得電池的狀態,通常的做法是監聽ACTION_BATTERY_CHANGED這個intent,只能在收到這個intent的時候才能取得電池的狀態資訊,有沒有同步取得電池資訊的辦法呢?
實際上,系統driver維護著儲存電池資訊的一組檔案。
/sys/class/power_supply/ac/online AC電源連線狀態
/sys/class/power_supply/usb/online USB電源連線狀態
/sys/class/power_supply/battery/status 充電狀態
/sys/class/power_supply/battery/health 電池狀態
/sys/class/power_supply/battery/present 使用狀態
/sys/class/power_supply/battery/capacity 電池level
/sys/class/power_supply/battery/batt_vol 電池電壓
/sys/class/power_supply/battery/batt_temp 電池溫度
/sys/class/power_supply/battery/technology 電池技術
當電池狀態發生變化時,driver會更新這些檔案,因此在應用程式中通過讀取這些檔案的辦法,可以做到同步取得電池資訊。
6、獲取手機各種狀態資訊
TelephonyManager tm = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
/*
* 電話狀態:
* 1.tm.CALL_STATE_IDLE=0 無活動
* 2.tm.CALL_STATE_RINGING=1 響鈴
* 3.tm.CALL_STATE_OFFHOOK=2 摘機
*/
tm.getCallState();//int
/*
* 電話方位:
*
*/
tm.getCellLocation();//CellLocation
/*
* 唯一的裝置ID:
* GSM手機的 IMEI 和 CDMA手機的 MEID.
* Return null if device ID is not available.
*/
tm.getDeviceId();//String
/*
* 裝置的軟體版本號:
* 例如:the IMEI/SV(software version) for GSM phones.
* Return null if the software version is not available.
*/
tm.getDeviceSoftwareVersion();//String
/*
* 手機號:
* GSM手機的 MSISDN.
* Return null if it is unavailable.
*/
tm.getLine1Number();//String
/*
* 附近的電話的資訊:
* 型別:List<NeighboringCellInfo>
* 需要許可權:android.Manifest.permission#ACCESS_COARSE_UPDATES
*/
tm.getNeighboringCellInfo();//List<NeighboringCellInfo>
/*
* 獲取ISO標準的國家碼,即國際長途區號。
* 注意:僅當用戶已在網路註冊後有效。
* 在CDMA網路中結果也許不可靠。
*/
tm.getNetworkCountryIso();//String
/*
* MCC+MNC(mobile country code + mobile network code)
* 注意:僅當用戶已在網路註冊時有效。
* 在CDMA網路中結果也許不可靠。
*/
tm.getNetworkOperator();//String
/*
* 按照字母次序的current registered operator(當前已註冊的使用者)的名字
* 注意:僅當用戶已在網路註冊時有效。
* 在CDMA網路中結果也許不可靠。
*/
tm.getNetworkOperatorName();//String
/*
* 當前使用的網路型別:
* 例如: NETWORK_TYPE_UNKNOWN 網路型別未知 0
NETWORK_TYPE_GPRS GPRS網路 1
NETWORK_TYPE_EDGE EDGE網路 2
NETWORK_TYPE_UMTS UMTS網路 3
NETWORK_TYPE_HSDPA HSDPA網路 8
NETWORK_TYPE_HSUPA HSUPA網路 9
NETWORK_TYPE_HSPA HSPA網路 10
NETWORK_TYPE_CDMA CDMA網路,IS95A 或 IS95B. 4
NETWORK_TYPE_EVDO_0 EVDO網路, revision 0. 5
NETWORK_TYPE_EVDO_A EVDO網路, revision A. 6
NETWORK_TYPE_1xRTT 1xRTT網路 7
*/
tm.getNetworkType();//int
/*
* 手機型別:
* 例如: PHONE_TYPE_NONE 無訊號
PHONE_TYPE_GSM GSM訊號
PHONE_TYPE_CDMA CDMA訊號
*/
tm.getPhoneType();//int
/*
* Returns the ISO country code equivalent for the SIM provider's country code.
* 獲取ISO國家碼,相當於提供SIM卡的國家碼。
*
*/
tm.getSimCountryIso();//String
/*
* Returns the MCC+MNC (mobile country code + mobile network code) of the provider of the SIM. 5 or 6 decimal digits.
* 獲取SIM卡提供的移動國家碼和行動網路碼.5或6位的十進位制數字.
* SIM卡的狀態必須是 SIM_STATE_READY(使用getSimState()判斷).
*/
tm.getSimOperator();//String
/*
* 服務商名稱:
* 例如:中國移動、聯通
* SIM卡的狀態必須是 SIM_STATE_READY(使用getSimState()判斷).
*/
tm.getSimOperatorName();//String
/*
* SIM卡的序列號:
* 需要許可權:READ_PHONE_STATE
*/
tm.getSimSerialNumber();//String
/*
* SIM的狀態資訊:
* SIM_STATE_UNKNOWN 未知狀態 0
SIM_STATE_ABSENT 沒插卡 1
SIM_STATE_PIN_REQUIRED 鎖定狀態,需要使用者的PIN碼解鎖 2
SIM_STATE_PUK_REQUIRED 鎖定狀態,需要使用者的PUK碼解鎖 3
SIM_STATE_NETWORK_LOCKED 鎖定狀態,需要網路的PIN碼解鎖 4
SIM_STATE_READY 就緒狀態 5
*/
tm.getSimState();//int
/*
* 唯一的使用者ID:
* 例如:IMSI(國際移動使用者識別碼) for a GSM phone.
* 需要許可權:READ_PHONE_STATE
*/
tm.getSubscriberId();//String
/*
* 取得和語音郵件相關的標籤,即為識別符
* 需要許可權:READ_PHONE_STATE
*/
tm.getVoiceMailAlphaTag();//String
/*
* 獲取語音郵件號碼:
* 需要許可權:READ_PHONE_STATE
*/
tm.getVoiceMailNumber();//String
/*
* ICC卡是否存在
*/
tm.hasIccCard();//boolean
/*
* 是否漫遊:
* (在GSM用途下)
*/
tm.isNetworkRoaming();//
值得注意的是,這個需要android.permission.READ_PHONE_STATE許可權。
6、獲取流量資訊
有兩種方法,一種是使用TrafficStats類,另一種就是讀取系統流量檔案:/proc/net/xt_qtaguid/stats