| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.settings.deviceinfo; |
| |
| import android.bluetooth.BluetoothAdapter; |
| import android.content.BroadcastReceiver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.content.res.Resources; |
| import android.net.wifi.WifiInfo; |
| import android.net.wifi.WifiManager; |
| import android.os.BatteryManager; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import android.os.Message; |
| import android.os.SystemClock; |
| import android.os.SystemProperties; |
| import android.preference.Preference; |
| import android.preference.PreferenceActivity; |
| import android.telephony.PhoneNumberUtils; |
| import android.telephony.PhoneStateListener; |
| import android.telephony.ServiceState; |
| import android.telephony.TelephonyManager; |
| import android.text.TextUtils; |
| |
| import com.android.internal.telephony.Phone; |
| import com.android.internal.telephony.PhoneFactory; |
| import com.android.internal.telephony.PhoneStateIntentReceiver; |
| import com.android.internal.telephony.TelephonyProperties; |
| import com.android.settings.R; |
| |
| import java.lang.ref.WeakReference; |
| |
| /** |
| * Display the following information |
| * # Phone Number |
| * # Network |
| * # Roaming |
| * # Device Id (IMEI in GSM and MEID in CDMA) |
| * # Network type |
| * # Signal Strength |
| * # Battery Strength : TODO |
| * # Uptime |
| * # Awake Time |
| * # XMPP/buzz/tickle status : TODO |
| * |
| */ |
| public class Status extends PreferenceActivity { |
| |
| private static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address"; |
| private static final String KEY_BT_ADDRESS = "bt_address"; |
| private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200; |
| private static final int EVENT_SERVICE_STATE_CHANGED = 300; |
| |
| private static final int EVENT_UPDATE_STATS = 500; |
| |
| private TelephonyManager mTelephonyManager; |
| private Phone mPhone = null; |
| private PhoneStateIntentReceiver mPhoneStateReceiver; |
| private Resources mRes; |
| private Preference mSignalStrength; |
| private Preference mUptime; |
| |
| private static String sUnknown; |
| |
| private Preference mBatteryStatus; |
| private Preference mBatteryLevel; |
| |
| private Handler mHandler; |
| |
| private static class MyHandler extends Handler { |
| private WeakReference<Status> mStatus; |
| |
| public MyHandler(Status activity) { |
| mStatus = new WeakReference<Status>(activity); |
| } |
| |
| @Override |
| public void handleMessage(Message msg) { |
| Status status = mStatus.get(); |
| if (status == null) { |
| return; |
| } |
| |
| switch (msg.what) { |
| case EVENT_SIGNAL_STRENGTH_CHANGED: |
| status.updateSignalStrength(); |
| break; |
| |
| case EVENT_SERVICE_STATE_CHANGED: |
| ServiceState serviceState = status.mPhoneStateReceiver.getServiceState(); |
| status.updateServiceState(serviceState); |
| break; |
| |
| case EVENT_UPDATE_STATS: |
| status.updateTimes(); |
| sendEmptyMessageDelayed(EVENT_UPDATE_STATS, 1000); |
| break; |
| } |
| } |
| } |
| |
| private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() { |
| |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| String action = intent.getAction(); |
| if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { |
| |
| int level = intent.getIntExtra("level", 0); |
| int scale = intent.getIntExtra("scale", 100); |
| |
| mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%"); |
| |
| int plugType = intent.getIntExtra("plugged", 0); |
| int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN); |
| String statusString; |
| if (status == BatteryManager.BATTERY_STATUS_CHARGING) { |
| statusString = getString(R.string.battery_info_status_charging); |
| if (plugType > 0) { |
| statusString = statusString + " " + getString( |
| (plugType == BatteryManager.BATTERY_PLUGGED_AC) |
| ? R.string.battery_info_status_charging_ac |
| : R.string.battery_info_status_charging_usb); |
| } |
| } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { |
| statusString = getString(R.string.battery_info_status_discharging); |
| } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { |
| statusString = getString(R.string.battery_info_status_not_charging); |
| } else if (status == BatteryManager.BATTERY_STATUS_FULL) { |
| statusString = getString(R.string.battery_info_status_full); |
| } else { |
| statusString = getString(R.string.battery_info_status_unknown); |
| } |
| mBatteryStatus.setSummary(statusString); |
| } |
| } |
| }; |
| |
| private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { |
| @Override |
| public void onDataConnectionStateChanged(int state) { |
| updateDataState(); |
| updateNetworkType(); |
| } |
| }; |
| |
| @Override |
| protected void onCreate(Bundle icicle) { |
| super.onCreate(icicle); |
| Preference removablePref; |
| |
| mHandler = new MyHandler(this); |
| |
| mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); |
| |
| addPreferencesFromResource(R.xml.device_info_status); |
| mBatteryLevel = findPreference("battery_level"); |
| mBatteryStatus = findPreference("battery_status"); |
| |
| mRes = getResources(); |
| if (sUnknown == null) { |
| sUnknown = mRes.getString(R.string.device_info_default); |
| } |
| |
| mPhone = PhoneFactory.getDefaultPhone(); |
| // Note - missing in zaku build, be careful later... |
| mSignalStrength = findPreference("signal_strength"); |
| mUptime = findPreference("up_time"); |
| |
| //NOTE "imei" is the "Device ID" since it represents the IMEI in GSM and the MEID in CDMA |
| if (mPhone.getPhoneName().equals("CDMA")) { |
| setSummaryText("meid_number", mPhone.getMeid()); |
| setSummaryText("min_number", mPhone.getCdmaMin()); |
| setSummaryText("prl_version", mPhone.getCdmaPrlVersion()); |
| |
| // device is not GSM/UMTS, do not display GSM/UMTS features |
| // check Null in case no specified preference in overlay xml |
| removablePref = findPreference("imei"); |
| if (removablePref != null) { |
| getPreferenceScreen().removePreference(removablePref); |
| } |
| removablePref = findPreference("imei_sv"); |
| if (removablePref != null) { |
| getPreferenceScreen().removePreference(removablePref); |
| } |
| } else { |
| setSummaryText("imei", mPhone.getDeviceId()); |
| |
| setSummaryText("imei_sv", |
| ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)) |
| .getDeviceSoftwareVersion()); |
| |
| // device is not CDMA, do not display CDMA features |
| // check Null in case no specified preference in overlay xml |
| removablePref = findPreference("prl_version"); |
| if (removablePref != null) { |
| getPreferenceScreen().removePreference(removablePref); |
| } |
| removablePref = findPreference("meid_number"); |
| if (removablePref != null) { |
| getPreferenceScreen().removePreference(removablePref); |
| } |
| removablePref = findPreference("min_number"); |
| if (removablePref != null) { |
| getPreferenceScreen().removePreference(removablePref); |
| } |
| } |
| |
| String rawNumber = mPhone.getLine1Number(); // may be null or empty |
| String formattedNumber = null; |
| if (!TextUtils.isEmpty(rawNumber)) { |
| formattedNumber = PhoneNumberUtils.formatNumber(rawNumber); |
| } |
| // If formattedNumber is null or empty, it'll display as "Unknown". |
| setSummaryText("number", formattedNumber); |
| |
| mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler); |
| mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED); |
| mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED); |
| |
| setWifiStatus(); |
| setBtStatus(); |
| } |
| |
| @Override |
| protected void onResume() { |
| super.onResume(); |
| |
| mPhoneStateReceiver.registerIntent(); |
| registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); |
| |
| updateSignalStrength(); |
| updateServiceState(mPhone.getServiceState()); |
| updateDataState(); |
| |
| mTelephonyManager.listen(mPhoneStateListener, |
| PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); |
| |
| mHandler.sendEmptyMessage(EVENT_UPDATE_STATS); |
| } |
| |
| @Override |
| public void onPause() { |
| super.onPause(); |
| |
| mPhoneStateReceiver.unregisterIntent(); |
| mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); |
| unregisterReceiver(mBatteryInfoReceiver); |
| mHandler.removeMessages(EVENT_UPDATE_STATS); |
| } |
| |
| /** |
| * @param preference The key for the Preference item |
| * @param property The system property to fetch |
| * @param alt The default value, if the property doesn't exist |
| */ |
| private void setSummary(String preference, String property, String alt) { |
| try { |
| findPreference(preference).setSummary( |
| SystemProperties.get(property, alt)); |
| } catch (RuntimeException e) { |
| |
| } |
| } |
| |
| private void setSummaryText(String preference, String text) { |
| if (TextUtils.isEmpty(text)) { |
| text = sUnknown; |
| } |
| // some preferences may be missing |
| if (findPreference(preference) != null) { |
| findPreference(preference).setSummary(text); |
| } |
| } |
| |
| private void updateNetworkType() { |
| // Whether EDGE, UMTS, etc... |
| setSummary("network_type", TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, sUnknown); |
| } |
| |
| private void updateDataState() { |
| int state = mTelephonyManager.getDataState(); |
| String display = mRes.getString(R.string.radioInfo_unknown); |
| |
| switch (state) { |
| case TelephonyManager.DATA_CONNECTED: |
| display = mRes.getString(R.string.radioInfo_data_connected); |
| break; |
| case TelephonyManager.DATA_SUSPENDED: |
| display = mRes.getString(R.string.radioInfo_data_suspended); |
| break; |
| case TelephonyManager.DATA_CONNECTING: |
| display = mRes.getString(R.string.radioInfo_data_connecting); |
| break; |
| case TelephonyManager.DATA_DISCONNECTED: |
| display = mRes.getString(R.string.radioInfo_data_disconnected); |
| break; |
| } |
| |
| setSummaryText("data_state", display); |
| } |
| |
| private void updateServiceState(ServiceState serviceState) { |
| int state = serviceState.getState(); |
| String display = mRes.getString(R.string.radioInfo_unknown); |
| |
| switch (state) { |
| case ServiceState.STATE_IN_SERVICE: |
| display = mRes.getString(R.string.radioInfo_service_in); |
| break; |
| case ServiceState.STATE_OUT_OF_SERVICE: |
| case ServiceState.STATE_EMERGENCY_ONLY: |
| display = mRes.getString(R.string.radioInfo_service_out); |
| break; |
| case ServiceState.STATE_POWER_OFF: |
| display = mRes.getString(R.string.radioInfo_service_off); |
| break; |
| } |
| |
| setSummaryText("service_state", display); |
| |
| if (serviceState.getRoaming()) { |
| setSummaryText("roaming_state", mRes.getString(R.string.radioInfo_roaming_in)); |
| } else { |
| setSummaryText("roaming_state", mRes.getString(R.string.radioInfo_roaming_not)); |
| } |
| setSummaryText("operator_name", serviceState.getOperatorAlphaLong()); |
| } |
| |
| void updateSignalStrength() { |
| // TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener |
| // should probably used instead. |
| |
| // not loaded in some versions of the code (e.g., zaku) |
| if (mSignalStrength != null) { |
| int state = |
| mPhoneStateReceiver.getServiceState().getState(); |
| Resources r = getResources(); |
| |
| if ((ServiceState.STATE_OUT_OF_SERVICE == state) || |
| (ServiceState.STATE_POWER_OFF == state)) { |
| mSignalStrength.setSummary("0"); |
| } |
| |
| int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm(); |
| |
| if (-1 == signalDbm) signalDbm = 0; |
| |
| int signalAsu = mPhoneStateReceiver.getSignalStrength(); |
| |
| if (-1 == signalAsu) signalAsu = 0; |
| |
| mSignalStrength.setSummary(String.valueOf(signalDbm) + " " |
| + r.getString(R.string.radioInfo_display_dbm) + " " |
| + String.valueOf(signalAsu) + " " |
| + r.getString(R.string.radioInfo_display_asu)); |
| } |
| } |
| |
| private void setWifiStatus() { |
| WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); |
| WifiInfo wifiInfo = wifiManager.getConnectionInfo(); |
| |
| Preference wifiMacAddressPref = findPreference(KEY_WIFI_MAC_ADDRESS); |
| String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress(); |
| wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress |
| : getString(R.string.status_unavailable)); |
| } |
| |
| private void setBtStatus() { |
| BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter(); |
| Preference btAddressPref = findPreference(KEY_BT_ADDRESS); |
| |
| if (bluetooth == null) { |
| // device not BT capable |
| getPreferenceScreen().removePreference(btAddressPref); |
| } else { |
| String address = bluetooth.isEnabled() ? bluetooth.getAddress() : null; |
| btAddressPref.setSummary(!TextUtils.isEmpty(address) ? address |
| : getString(R.string.status_unavailable)); |
| } |
| } |
| |
| void updateTimes() { |
| long at = SystemClock.uptimeMillis() / 1000; |
| long ut = SystemClock.elapsedRealtime() / 1000; |
| |
| if (ut == 0) { |
| ut = 1; |
| } |
| |
| mUptime.setSummary(convert(ut)); |
| } |
| |
| private String pad(int n) { |
| if (n >= 10) { |
| return String.valueOf(n); |
| } else { |
| return "0" + String.valueOf(n); |
| } |
| } |
| |
| private String convert(long t) { |
| int s = (int)(t % 60); |
| int m = (int)((t / 60) % 60); |
| int h = (int)((t / 3600)); |
| |
| return h + ":" + pad(m) + ":" + pad(s); |
| } |
| } |