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
关于第一种方法:参考文章:Android中TrafficStats流量监控类
参考文章:
获取Android手机各种状态信息
Android 获取系统 cpu 信息,内存,版本,电量等信息