Android - 簡介如何取得Android設備相關資訊
取得Android設備的資訊是很重要的,因為在很多情境下,例如:要取得目前使用的網路狀態來識別是否適合大量檔案下載;
或是識別目前使用Location的資訊是來源GPS或WIF…等,包括還有在提供給用戶做App錯誤回報時,也希望把用戶設備的相關
資訊取出來做為查詢或測試App時的一個依據。因此,這些重要的情境都是我們需要的,本篇就整理了幾個比較重要的部分:
〉取得SIM Card相關資訊 - TelephonyManager:
要取得有關電話的相關資訊,一定要了解一下「TelephonyManager」這個模組的功能,才有辦法往下找到需要的電話資訊。
TelephonyManager提供相關該設備上所有Telephony Service的資訊,App可以透過該固定模組的方法與參數取得目前設備的
資訊與通訊的服務狀態,使用該模組不需要Instance它,而直接透過「Context.getSystemService(Context.TELEPHONY_SERVICE)」
即可以進行操作,但別忘記在AndroidManifest.xml加上Uese-Permission:
1: <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
往下就直接透過Code來介紹幾個常需要被擷取出來的設備資訊:
1: package com.android.CDevice;
2:
3: import android.content.Context;
4: import android.telephony.TelephonyManager;
5:
6: public class PhoneHandler {
7:
8: TelephonyManager mTelephonyMgr;
9: Context gContext;
10:
11: public PhoneHandler(Context pContext){
12: gContext = pContext;
13: }
14:
15: public String getMyPhoneInformation(){
16: mTelephonyMgr = (TelephonyManager) gContext.getSystemService(Context.TELEPHONY_SERVICE);
17:
18: StringBuilder tBuilder = new StringBuilder();
19:
20: tBuilder.append(String.format("Device ID: %s\n", mTelephonyMgr.getDeviceId()));
21: tBuilder.append(String.format("Device Software Version: %s\n", mTelephonyMgr.getDeviceSoftwareVersion()));
22:
23: tBuilder.append(String.format("Network Operator: %s\n", mTelephonyMgr.getNetworkOperator()));
24: tBuilder.append(String.format("Network Operator Name: %s\n", mTelephonyMgr.getNetworkOperatorName()));
25: tBuilder.append(String.format("Network Type: %s\n", IdentifyNetworkType(mTelephonyMgr.getNetworkType())));
26:
27: tBuilder.append(String.format("Phone Type: %s\n", IdentifyPhoneType(mTelephonyMgr.getPhoneType())));
28: tBuilder.append(String.format("SIM Serial Number: %s\n", mTelephonyMgr.getSimSerialNumber()));
29: tBuilder.append(String.format("SIM State: %s\n", mTelephonyMgr.getSimState()));
30: tBuilder.append(String.format("Phone Number: %s\n", mTelephonyMgr.getLine1Number()));
31:
32: tBuilder.append(String.format("Data Connection State: %s\n", IdentifyDataState(mTelephonyMgr.getDataState ())));
33: tBuilder.append(String.format("Type of activity on a data connection: %s\n", mTelephonyMgr.getDataActivity()));
34:
35: tBuilder.append(String.format("Cell State: %s\n", IdentifySimeState(mTelephonyMgr.getCallState())));
36: tBuilder.append(String.format("Cell Location: %s\n", mTelephonyMgr.getCellLocation().toString()));
37:
38: return tBuilder.toString();
39: }
40:
41: /**
42: * 識別網路類型。
43: * @param pValue
44: * @return
45: */
46: private String IdentifyNetworkType(int pValue) {
47: String tResult = "";
48: switch(pValue){
49: case TelephonyManager.NETWORK_TYPE_UNKNOWN:
50: tResult = "UNKNOWN";
51: break;
52: case TelephonyManager.NETWORK_TYPE_GPRS:
53: tResult = "GPRS";
54: break;
55: case TelephonyManager.NETWORK_TYPE_EDGE:
56: tResult = "EDGE";
57: break;
58: case TelephonyManager.NETWORK_TYPE_UMTS:
59: tResult = "UMTS";
60: break;
61: case TelephonyManager.NETWORK_TYPE_HSDPA:
62: tResult = "HSDPA";
63: break;
64: case TelephonyManager.NETWORK_TYPE_HSUPA:
65: tResult = "HSUPA";
66: break;
67: case TelephonyManager.NETWORK_TYPE_HSPA:
68: tResult = "HSPA";
69: break;
70: case TelephonyManager.NETWORK_TYPE_CDMA:
71: tResult = "CDMA";
72: break;
73: case TelephonyManager.NETWORK_TYPE_EVDO_0:
74: tResult = "EVDO_0";
75: break;
76: case TelephonyManager.NETWORK_TYPE_EVDO_A:
77: tResult = "EVDO_A";
78: break;
79: case TelephonyManager.NETWORK_TYPE_EVDO_B:
80: tResult = "EVDO_B";
81: break;
82: case TelephonyManager.NETWORK_TYPE_1xRTT:
83: tResult = "1xRTT";
84: break;
85: case TelephonyManager.NETWORK_TYPE_IDEN:
86: tResult = "IDEN";
87: break;
88: }
89: return tResult;
90: }
91:
92: /**
93: * 識別電話系統類型。
94: * @param pValue
95: * @return
96: */
97: private String IdentifyPhoneType(int pValue){
98: String tResult = "";
99: switch(pValue){
100: case TelephonyManager.PHONE_TYPE_NONE:
101: tResult = "NONE";
102: break;
103: case TelephonyManager.PHONE_TYPE_GSM:
104: tResult = "GSM";
105: break;
106: case TelephonyManager.PHONE_TYPE_CDMA:
107: tResult = "CDMA";
108: break;
109: }
110: return tResult;
111: }
112:
113: /**
114: * 識別行動網路連線狀態。
115: * @param pValue
116: * @return
117: */
118: private String IdentifyDataState(int pValue){
119: String tResult = "";
120: switch (pValue){
121: case TelephonyManager.DATA_DISCONNECTED:
122: tResult = "DATA_DISCONNECTED";
123: break;
124: case TelephonyManager.DATA_CONNECTING:
125: tResult = "DATA_CONNECTING";
126: break;
127: case TelephonyManager.DATA_CONNECTED:
128: tResult = "DATA_CONNECTED";
129: break;
130: case TelephonyManager.DATA_SUSPENDED:
131: tResult = "DATA_SUSPENDED";
132: break;
133: }
134: return tResult;
135: }
136:
137: /**
138: * 識別行動網路運作狀態。
139: * @param pValue
140: * @return
141: */
142: private String IdentifyDataActivity(int pValue){
143: String tResult = "";
144: switch (pValue){
145: case TelephonyManager.DATA_ACTIVITY_NONE:
146: tResult = "DATA_ACTIVITY_NONE";
147: break;
148: case TelephonyManager.DATA_ACTIVITY_IN:
149: tResult = "DATA_ACTIVITY_IN";
150: break;
151: case TelephonyManager.DATA_ACTIVITY_OUT:
152: tResult = "DATA_ACTIVITY_OUT";
153: break;
154: case TelephonyManager.DATA_ACTIVITY_INOUT:
155: tResult = "DATA_ACTIVITY_INOUT";
156: break;
157: case TelephonyManager.DATA_ACTIVITY_DORMANT:
158: tResult = "DATA_ACTIVITY_DORMANT";
159: break;
160: }
161: return tResult;
162: }
163:
164: /**
165: * 識別SIM卡狀態。
166: * @param pValue
167: * @return
168: */
169: private String IdentifySimeState(int pValue){
170: String tResult = "";
171: switch (pValue){
172: case TelephonyManager.SIM_STATE_UNKNOWN:
173: tResult = "SIM_STATE_UNKNOWN";
174: break;
175: case TelephonyManager.SIM_STATE_ABSENT:
176: tResult = "SIM_STATE_ABSENT";
177: break;
178: case TelephonyManager.SIM_STATE_PIN_REQUIRED:
179: tResult = "SIM_STATE_PIN_REQUIRED";
180: break;
181: case TelephonyManager.SIM_STATE_PUK_REQUIRED:
182: tResult = "SIM_STATE_PUK_REQUIRED";
183: break;
184: case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
185: tResult = "SIM_STATE_NETWORK_LOCKED";
186: break;
187: case TelephonyManager.SIM_STATE_READY:
188: tResult = "SIM_STATE_READY";
189: break;
190: }
191: return tResult;
192: }
193: }
[注意]
a. 上述可以看到SIM Serial Number: null主要是因為我測試的設備沒有SIM卡是直接燒錄的號碼,因此沒有取得值;
b. Phone Number: 0000000000:會出現這樣的結果,是因為SIM卡的關係,要看SIM製造商有沒有把號碼燒成SIM卡才有辦法取得;
〉取得Location定位資訊來源 - LocationManager:
之前有寫過<Android - 定位資訊(GPS)相關類別使用說明>針對配合GPS取得定位資訊的文章,裡面有提到Android支援使用GPS或
WIFI進行定位的服務,其中有幾個必要的元件,一定要注意的,包括:
‧LocationManager:提供連結到系統的Location服務,取得此服務也代表允許Application可以進一步承接設備週期性更新的地理資訊。
‧LocationProvider:主要用於定義Location Provider為何(可能是GPS或Network),並且定期回報設備的地理資訊。
‧LocationListener:處理來自LocationManager發出觸發定位資訊或狀態改變的訊息。
更詳細取得Location的資訊與開發時要注意的問題,可以參考上述提到的文章,有比較詳細的解說。
〉取得Network網路連線類型 - ConnectivityManager:
在撰寫Android程式裡,如果App的功能一定要在有網路連線的情形下運作,那一定不可以忘記這個ConnectivityManager重要的模組。
該模組主要任務為:
(1) 監控目前網路狀態;
(2) 當遇到網路狀態改變時,負責發出變動的廣播訊息;
(3) 控制預設網路連線方式失敗時,可以指定切換使用的網路連線方式;
(4) 提供撰寫程式去查詢目前可使用網路連線項目中較好與較差的狀態;
然而,android.net.ConnectivityManager它與TelephonyManager一樣直接透過「Context.getSystemService(Context.CONNECTIVITY_SERVICE)
」 ,
就可以取得實例化出來的元件進行操作,當然,也別忘了在AndroidManifest.xml加上uses-permission:
1: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
接下來,將介紹幾個常用的方法:
1: package com.android.CDevice;
2:
3: import android.content.Context;
4: import android.net.ConnectivityManager;
5: import android.net.NetworkInfo;
6:
7: public class ConnectionManager {
8: private Context gContext = null;
9: private ConnectivityManager gConnMgr = null;
10:
11: public ConnectionManager(Context pContext){
12: gContext = pContext;
13: gConnMgr = (ConnectivityManager) gContext.getSystemService(Context.CONNECTIVITY_SERVICE);
14: }
15:
16: /**
17: * 取得目前手機使用的網路連線模式。
18: * @return
19: */
20: public String GetCurrentNetworkMode(){
21: StringBuilder tBuilder = new StringBuilder();
22: //取得目前正在使用網路連線模式
23: NetworkInfo tInfo = gConnMgr.getActiveNetworkInfo();
24: if (tInfo != null){
25: tBuilder.append(String.format("Network Type: %s\n", tInfo.getTypeName()));
26: tBuilder.append(String.format("Network State: %s\n", tInfo.getState().toString()));
27: tBuilder.append(String.format("Network is Connecting: %s\n", tInfo.isConnectedOrConnecting()));
28: tBuilder.append(String.format("Network is Connected: %s\n", tInfo.isConnected()));
29: tBuilder.append(String.format("Network is Available: %s\n", tInfo.isAvailable()));
30: tBuilder.append(String.format("Network is Roaming: %s\n", tInfo.isRoaming()));
31: tBuilder.append(String.format("Network is Failover: %s\n", tInfo.isFailover()));
32: }else {
33: tBuilder.append("No use Network Mode!!");
34: }
35: return tBuilder.toString();
36: }
37:
38: /**
39: * 取得所有手機可用的網路連線模式與資訊。
40: * @return
41: */
42: public String GetNetWorkInfo(){
43: //取得所有可使用網路連線模式
44: NetworkInfo[] tInfos = gConnMgr.getAllNetworkInfo();
45: String tReulst = "";
46: for (int i = 0; i< tInfos.length; i++){
47: StringBuilder tBuilder = new StringBuilder();
48: NetworkInfo tInfo = tInfos[i];
49: if (tInfo != null){
50: tBuilder.append(String.format("Network Type: %s\n", tInfo.getTypeName()));
51: tBuilder.append(String.format("Network State: %s\n", tInfo.getState().toString()));
52: tBuilder.append(String.format("Network is Connecting: %s\n", tInfo.isConnectedOrConnecting()));
53: tBuilder.append(String.format("Network is Connected: %s\n", tInfo.isConnected()));
54: tBuilder.append(String.format("Network is Available: %s\n", tInfo.isAvailable()));
55: tBuilder.append(String.format("Network is Roaming: %s\n", tInfo.isRoaming()));
56: tBuilder.append(String.format("Network is Failover: %s\n", tInfo.isFailover()));
57: }else {
58: tBuilder.append("No use Network Mode!!");
59: }
60: tBuilder.append("\n");
61:
62: tReulst += tBuilder.toString();
63: }
64: return tReulst;
65: }
66: }
[注意]
a. 上述中我寫了二個方法:GetCurrentNetworkMode(取得目前手機使用的網路連線模式)與GetNetWorkInfo(取得所有手機可用的網路連線模式與資訊);
b. 在取得NetworkInfo物件時,有可能會取得null的時候,要記得做判斷。
c. 如果你寫的程式有需要詢問目前用戶IP與Routing的狀態,可以再使用「requestRouteToHost」的方法。
======
以上是整理取得Android設備資訊中比較常用到的部分,由於本篇文章主要是直接透過程式碼來說明真正的結果,
我覺得閱讀起來會比較有感覺,因此,直接使用程式碼與結果來說明。另外,要特別注意的是:我在撰寫Android程式時,
在針對不同的Device要求取得Android資訊時,有時都會是null或取到跟其他不同的Android版本有不同的結果,
因此,在使用時還是要多測試一下,如果大家在使用時或看過更好的做法,也希望大家可以互相交流分享一下。非常的謝謝。
References:
‧[Android]利用 TelephonyManager 取得電信網路資訊
‧取得電信網路與手機相關資訊 - TelephonyManager與android.provider.Settings.System的應用
‧Android學習筆記 - 通話狀態(PhoneState)
‧Android 教你如何通过 LocationManager 获取得到当前位置坐标
‧Android中LocationManager的簡單使用,獲取當前位置
‧Android 偵測網路是否連線 & Android – 判斷手機是否連上網路 (ConnectivityManager)
‧[Android] ConnectivityManager monitor & android之ConnectivityManager简介,网络连接状态
‧Android 多語系模式開發 (必讀)