Status.java revision 489c7bff5c54c35e7156a99337d538e08f3aab7f
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings.deviceinfo; 18 19import android.bluetooth.BluetoothAdapter; 20import android.content.BroadcastReceiver; 21import android.content.Context; 22import android.content.Intent; 23import android.content.IntentFilter; 24import android.content.res.Resources; 25import android.net.wifi.WifiInfo; 26import android.net.wifi.WifiManager; 27import android.os.BatteryManager; 28import android.os.Build; 29import android.os.Bundle; 30import android.os.Handler; 31import android.os.Message; 32import android.os.SystemClock; 33import android.os.SystemProperties; 34import android.preference.Preference; 35import android.preference.PreferenceActivity; 36import android.telephony.PhoneNumberUtils; 37import android.telephony.PhoneStateListener; 38import android.telephony.ServiceState; 39import android.telephony.TelephonyManager; 40import android.text.TextUtils; 41 42import com.android.internal.telephony.Phone; 43import com.android.internal.telephony.PhoneFactory; 44import com.android.internal.telephony.PhoneStateIntentReceiver; 45import com.android.internal.telephony.TelephonyProperties; 46import com.android.settings.R; 47import com.android.settings.Utils; 48 49import java.lang.ref.WeakReference; 50 51/** 52 * Display the following information 53 * # Phone Number 54 * # Network 55 * # Roaming 56 * # Device Id (IMEI in GSM and MEID in CDMA) 57 * # Network type 58 * # Signal Strength 59 * # Battery Strength : TODO 60 * # Uptime 61 * # Awake Time 62 * # XMPP/buzz/tickle status : TODO 63 * 64 */ 65public class Status extends PreferenceActivity { 66 67 private static final String KEY_SERVICE_STATE = "service_state"; 68 private static final String KEY_OPERATOR_NAME = "operator_name"; 69 private static final String KEY_ROAMING_STATE = "roaming_state"; 70 private static final String KEY_NETWORK_TYPE = "network_type"; 71 private static final String KEY_PHONE_NUMBER = "number"; 72 private static final String KEY_IMEI_SV = "imei_sv"; 73 private static final String KEY_IMEI = "imei"; 74 private static final String KEY_PRL_VERSION = "prl_version"; 75 private static final String KEY_MIN_NUMBER = "min_number"; 76 private static final String KEY_MEID_NUMBER = "meid_number"; 77 private static final String KEY_SIGNAL_STRENGTH = "signal_strength"; 78 private static final String KEY_BATTERY_STATUS = "battery_status"; 79 private static final String KEY_BATTERY_LEVEL = "battery_level"; 80 private static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address"; 81 private static final String KEY_BT_ADDRESS = "bt_address"; 82 private static final String KEY_SERIAL_NUMBER = "serial_number"; 83 84 private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200; 85 private static final int EVENT_SERVICE_STATE_CHANGED = 300; 86 87 private static final int EVENT_UPDATE_STATS = 500; 88 89 private TelephonyManager mTelephonyManager; 90 private Phone mPhone = null; 91 private PhoneStateIntentReceiver mPhoneStateReceiver; 92 private Resources mRes; 93 private Preference mSignalStrength; 94 private Preference mUptime; 95 96 private static String sUnknown; 97 98 private Preference mBatteryStatus; 99 private Preference mBatteryLevel; 100 101 private Handler mHandler; 102 103 private static class MyHandler extends Handler { 104 private WeakReference<Status> mStatus; 105 106 public MyHandler(Status activity) { 107 mStatus = new WeakReference<Status>(activity); 108 } 109 110 @Override 111 public void handleMessage(Message msg) { 112 Status status = mStatus.get(); 113 if (status == null) { 114 return; 115 } 116 117 switch (msg.what) { 118 case EVENT_SIGNAL_STRENGTH_CHANGED: 119 status.updateSignalStrength(); 120 break; 121 122 case EVENT_SERVICE_STATE_CHANGED: 123 ServiceState serviceState = status.mPhoneStateReceiver.getServiceState(); 124 status.updateServiceState(serviceState); 125 break; 126 127 case EVENT_UPDATE_STATS: 128 status.updateTimes(); 129 sendEmptyMessageDelayed(EVENT_UPDATE_STATS, 1000); 130 break; 131 } 132 } 133 } 134 135 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() { 136 137 @Override 138 public void onReceive(Context context, Intent intent) { 139 String action = intent.getAction(); 140 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 141 142 int level = intent.getIntExtra("level", 0); 143 int scale = intent.getIntExtra("scale", 100); 144 145 mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%"); 146 147 int plugType = intent.getIntExtra("plugged", 0); 148 int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN); 149 String statusString; 150 if (status == BatteryManager.BATTERY_STATUS_CHARGING) { 151 statusString = getString(R.string.battery_info_status_charging); 152 if (plugType > 0) { 153 statusString = statusString + " " + getString( 154 (plugType == BatteryManager.BATTERY_PLUGGED_AC) 155 ? R.string.battery_info_status_charging_ac 156 : R.string.battery_info_status_charging_usb); 157 } 158 } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { 159 statusString = getString(R.string.battery_info_status_discharging); 160 } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { 161 statusString = getString(R.string.battery_info_status_not_charging); 162 } else if (status == BatteryManager.BATTERY_STATUS_FULL) { 163 statusString = getString(R.string.battery_info_status_full); 164 } else { 165 statusString = getString(R.string.battery_info_status_unknown); 166 } 167 mBatteryStatus.setSummary(statusString); 168 } 169 } 170 }; 171 172 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 173 @Override 174 public void onDataConnectionStateChanged(int state) { 175 updateDataState(); 176 updateNetworkType(); 177 } 178 }; 179 180 @Override 181 protected void onCreate(Bundle icicle) { 182 super.onCreate(icicle); 183 Preference removablePref; 184 185 mHandler = new MyHandler(this); 186 187 mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); 188 189 addPreferencesFromResource(R.xml.device_info_status); 190 mBatteryLevel = findPreference(KEY_BATTERY_LEVEL); 191 mBatteryStatus = findPreference(KEY_BATTERY_STATUS); 192 193 mRes = getResources(); 194 if (sUnknown == null) { 195 sUnknown = mRes.getString(R.string.device_info_default); 196 } 197 198 mPhone = PhoneFactory.getDefaultPhone(); 199 // Note - missing in zaku build, be careful later... 200 mSignalStrength = findPreference(KEY_SIGNAL_STRENGTH); 201 mUptime = findPreference("up_time"); 202 203 //NOTE "imei" is the "Device ID" since it represents the IMEI in GSM and the MEID in CDMA 204 if (mPhone.getPhoneName().equals("CDMA")) { 205 setSummaryText(KEY_MEID_NUMBER, mPhone.getMeid()); 206 setSummaryText(KEY_MIN_NUMBER, mPhone.getCdmaMin()); 207 setSummaryText(KEY_PRL_VERSION, mPhone.getCdmaPrlVersion()); 208 209 // device is not GSM/UMTS, do not display GSM/UMTS features 210 // check Null in case no specified preference in overlay xml 211 removePreferenceFromScreen(KEY_IMEI); 212 removePreferenceFromScreen(KEY_IMEI_SV); 213 } else { 214 setSummaryText(KEY_IMEI, mPhone.getDeviceId()); 215 216 setSummaryText(KEY_IMEI_SV, 217 ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)) 218 .getDeviceSoftwareVersion()); 219 220 // device is not CDMA, do not display CDMA features 221 // check Null in case no specified preference in overlay xml 222 removePreferenceFromScreen(KEY_PRL_VERSION); 223 removePreferenceFromScreen(KEY_MEID_NUMBER); 224 removePreferenceFromScreen(KEY_MIN_NUMBER); 225 } 226 227 String rawNumber = mPhone.getLine1Number(); // may be null or empty 228 String formattedNumber = null; 229 if (!TextUtils.isEmpty(rawNumber)) { 230 formattedNumber = PhoneNumberUtils.formatNumber(rawNumber); 231 } 232 // If formattedNumber is null or empty, it'll display as "Unknown". 233 setSummaryText(KEY_PHONE_NUMBER, formattedNumber); 234 235 mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler); 236 mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED); 237 mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED); 238 239 setWifiStatus(); 240 setBtStatus(); 241 242 String serial = Build.SERIAL; 243 if (serial != null && !serial.equals("")) { 244 setSummaryText(KEY_SERIAL_NUMBER, serial); 245 } else { 246 removePreferenceFromScreen(KEY_SERIAL_NUMBER); 247 } 248 } 249 250 @Override 251 protected void onResume() { 252 super.onResume(); 253 254 mPhoneStateReceiver.registerIntent(); 255 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 256 257 updateSignalStrength(); 258 updateServiceState(mPhone.getServiceState()); 259 updateDataState(); 260 261 mTelephonyManager.listen(mPhoneStateListener, 262 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); 263 264 mHandler.sendEmptyMessage(EVENT_UPDATE_STATS); 265 } 266 267 @Override 268 public void onPause() { 269 super.onPause(); 270 271 mPhoneStateReceiver.unregisterIntent(); 272 mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); 273 unregisterReceiver(mBatteryInfoReceiver); 274 mHandler.removeMessages(EVENT_UPDATE_STATS); 275 } 276 277 /** 278 * Removes the specified preference, if it exists. 279 * @param key the key for the Preference item 280 */ 281 private void removePreferenceFromScreen(String key) { 282 Preference pref = findPreference(key); 283 if (pref != null) { 284 getPreferenceScreen().removePreference(pref); 285 } 286 } 287 288 /** 289 * @param preference The key for the Preference item 290 * @param property The system property to fetch 291 * @param alt The default value, if the property doesn't exist 292 */ 293 private void setSummary(String preference, String property, String alt) { 294 try { 295 findPreference(preference).setSummary( 296 SystemProperties.get(property, alt)); 297 } catch (RuntimeException e) { 298 299 } 300 } 301 302 private void setSummaryText(String preference, String text) { 303 if (TextUtils.isEmpty(text)) { 304 text = sUnknown; 305 } 306 // some preferences may be missing 307 if (findPreference(preference) != null) { 308 findPreference(preference).setSummary(text); 309 } 310 } 311 312 private void updateNetworkType() { 313 // Whether EDGE, UMTS, etc... 314 setSummary(KEY_NETWORK_TYPE, TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, sUnknown); 315 } 316 317 private void updateDataState() { 318 int state = mTelephonyManager.getDataState(); 319 String display = mRes.getString(R.string.radioInfo_unknown); 320 321 switch (state) { 322 case TelephonyManager.DATA_CONNECTED: 323 display = mRes.getString(R.string.radioInfo_data_connected); 324 break; 325 case TelephonyManager.DATA_SUSPENDED: 326 display = mRes.getString(R.string.radioInfo_data_suspended); 327 break; 328 case TelephonyManager.DATA_CONNECTING: 329 display = mRes.getString(R.string.radioInfo_data_connecting); 330 break; 331 case TelephonyManager.DATA_DISCONNECTED: 332 display = mRes.getString(R.string.radioInfo_data_disconnected); 333 break; 334 } 335 336 setSummaryText("data_state", display); 337 } 338 339 private void updateServiceState(ServiceState serviceState) { 340 int state = serviceState.getState(); 341 String display = mRes.getString(R.string.radioInfo_unknown); 342 343 switch (state) { 344 case ServiceState.STATE_IN_SERVICE: 345 display = mRes.getString(R.string.radioInfo_service_in); 346 break; 347 case ServiceState.STATE_OUT_OF_SERVICE: 348 case ServiceState.STATE_EMERGENCY_ONLY: 349 display = mRes.getString(R.string.radioInfo_service_out); 350 break; 351 case ServiceState.STATE_POWER_OFF: 352 display = mRes.getString(R.string.radioInfo_service_off); 353 break; 354 } 355 356 setSummaryText(KEY_SERVICE_STATE, display); 357 358 if (serviceState.getRoaming()) { 359 setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_in)); 360 } else { 361 setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_not)); 362 } 363 setSummaryText(KEY_OPERATOR_NAME, serviceState.getOperatorAlphaLong()); 364 } 365 366 void updateSignalStrength() { 367 // TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener 368 // should probably used instead. 369 370 // not loaded in some versions of the code (e.g., zaku) 371 if (mSignalStrength != null) { 372 int state = 373 mPhoneStateReceiver.getServiceState().getState(); 374 Resources r = getResources(); 375 376 if ((ServiceState.STATE_OUT_OF_SERVICE == state) || 377 (ServiceState.STATE_POWER_OFF == state)) { 378 mSignalStrength.setSummary("0"); 379 } 380 381 int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm(); 382 383 if (-1 == signalDbm) signalDbm = 0; 384 385 int signalAsu = mPhoneStateReceiver.getSignalStrength(); 386 387 if (-1 == signalAsu) signalAsu = 0; 388 389 mSignalStrength.setSummary(String.valueOf(signalDbm) + " " 390 + r.getString(R.string.radioInfo_display_dbm) + " " 391 + String.valueOf(signalAsu) + " " 392 + r.getString(R.string.radioInfo_display_asu)); 393 } 394 } 395 396 private void setWifiStatus() { 397 WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); 398 WifiInfo wifiInfo = wifiManager.getConnectionInfo(); 399 400 Preference wifiMacAddressPref = findPreference(KEY_WIFI_MAC_ADDRESS); 401 String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress(); 402 wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress 403 : getString(R.string.status_unavailable)); 404 } 405 406 private void setBtStatus() { 407 BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter(); 408 Preference btAddressPref = findPreference(KEY_BT_ADDRESS); 409 410 if (bluetooth == null) { 411 // device not BT capable 412 getPreferenceScreen().removePreference(btAddressPref); 413 } else { 414 String address = bluetooth.isEnabled() ? bluetooth.getAddress() : null; 415 btAddressPref.setSummary(!TextUtils.isEmpty(address) ? address 416 : getString(R.string.status_unavailable)); 417 } 418 } 419 420 void updateTimes() { 421 long at = SystemClock.uptimeMillis() / 1000; 422 long ut = SystemClock.elapsedRealtime() / 1000; 423 424 if (ut == 0) { 425 ut = 1; 426 } 427 428 mUptime.setSummary(convert(ut)); 429 } 430 431 private String pad(int n) { 432 if (n >= 10) { 433 return String.valueOf(n); 434 } else { 435 return "0" + String.valueOf(n); 436 } 437 } 438 439 private String convert(long t) { 440 int s = (int)(t % 60); 441 int m = (int)((t / 60) % 60); 442 int h = (int)((t / 3600)); 443 444 return h + ":" + pad(m) + ":" + pad(s); 445 } 446} 447