1.RelativeLayout有一点需要注意,因为它内部是通过多个View之间的关系而确定的框架,那么当其中某一个View因为某些需要调用GONE 来完全隐藏掉后,会影响与其相关联的Views。Android为我们提供了一个属性 alignWithParentIfMissing 用于解决类似问题,当某一个View无法找到与其相关联 的Views后将依据alignWithParentIfMissing 的设定判断是否与父级View对齐。
String srvcName = Context.TELEPHONY_SERVICE;
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(srvcName);
String phoneType = "Phone Type: " + telephonyManager.getPhoneType();
String deviceID = "Device ID: " + telephonyManager.getDeviceId();
String phoneNumber = "Phone Number: " + telephonyManager.getLine1Number();
String networkContry = "Network Country: " + telephonyManager.getNetworkCountryIso();
String networkName = "Network Name: " + telephonyManager.getNetworkOperatorName();
String networkType = "Network type: " + telephonyManager.getNetworkType();
String simCountry = "SIM Country: " + telephonyManager.getSimCountryIso();
String simName = "SIM Name: " + telephonyManager.getSimOperatorName();
String simNumber = "SIM Number: " + telephonyManager.getSimSerialNumber();
所有的设备都可以返回一个 TelephonyManager.getDeviceId()所有的GSM设备 (测试设备都装载有SIM卡) 可以返回一个TelephonyManager.getSimSerialNumber()所有的CDMA 设备对于 getSimSerialNumber() 却返回一个空值!所有添加有谷歌账户的设备可以返回一个 ANDROID_ID所有的CDMA设备对于 ANDROID_ID 和 TelephonyManager.getDeviceId() 返回相同的值(只要在设置时添加了谷歌账户)
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = ""
+ android.provider.Settings.Secure.getString(context
.getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice
.hashCode() << 32)
| tmSerial.hashCode());
deviceId = deviceUuid.toString();
如果你想得到设备的唯一序号, TelephonyManager.getDeviceId() 就足够了。但很明显暴露了DeviceID会使一些用户不满,所以最好把这些id加密了。实际上加密后的序号仍然可以唯一的识别该设备,并且不会明显的暴露用户的特定设备,例如,使用 String.hashCode() ,结合UUID
从Android 2.3开始提供了一个新的类StrictMode,可以帮助开发者改进他们的Android应用,StrictMode可以用于捕捉发生在应用程序主线程中耗时的磁盘、网络访问或函数调用,可以帮助开发者使其改进程序,使主线程处理UI和动画在磁盘读写和网络操作时变得更平滑,避免主线程被阻塞,导致ANR窗口的发生。
下面简要说明下Android 2.3新特性StrictMode限制模式的工作方式,见下面的代码:
publicvoid onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // 这里可以替换为detectAll() 就包括了磁盘读写和网络I/O
.penaltyLog() //打印logcat,当然也可以定位到dropbox,通过文件保存相应的log
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects() //探测SQLite数据库操作
.penaltyLog() //打印logcat
.penaltyDeath()
.build());
}
super.onCreate();
}
上述代码可以在Application的OnCreate中添加,这样就能在程序启动的最初一刻进行监控了
Android系统的“程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可。
异常处理类:
public class ErrorReporter implements Thread.UncaughtExceptionHandler {
private static Context context;
public static void installReporter(Context appContext) {
try {
Thread.setDefaultUncaughtExceptionHandler(new ErrorReporter());
context = appContext;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
showToast("Sorry. Something went wrong and it's reported. We will fix it soon!");
ex.printStackTrace();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
}
private void showToast(final String message) {
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
}
}
绑定异常处理类
ErrorReporter.installReporter(getApplicationContext());
"sdk".equals(Build.PRODUCT) //判断实在虚拟机中运行
isTaskRoot()//判断是不是task中最底层的activity