Menu Home

Android

Android:关于ViewGroup的ClipChildren

ClipChildren属性对需要做动画的View非常有用,特别是对ScaleAnimation。 需要注意的是ClipChildren = false只是告诉他的子View可以超出他本身的大小,并不是说他自己可以超出他的父View的大小,所以如果你想允许某个View超过其父View的边界,你需要一直找到最顶层的父View并设置ClipChildren = false。 下面需要提一下的是一个关于ClipChildren的坑,在4.2的系统上(4.3未测试,4.4及5.0版本没有这个 BUG),在启用了hardware accelerated的情况下,ScaleAnimation会出现撕裂等不流畅的现象,处理方法如下: if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { parentView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } 这里的parentView一定要是你启用了ClipChildren = false的那个ViewGroup,否则没有效果,最佳实践是只在需要做ScaleAnimation的时候才关闭硬件加速,做完动画后应该重新开启。 关于这个BUG的更多信息请移步:这里 关于更多Android Hardware Accelerated信息请阅读:这里

Android:监控电量

获取初始电量 Android系统发送的电量广播是一个sticky broadcast,所以可以通过给registerReceiver传递一个null参数来获取上次系统发送的电量广播。 private int getLastBatteryLevel() { Intent batteryIntent = registerReceiver(null, new IntentFilter( Intent.ACTION_BATTERY_CHANGED)); return batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); } 监控电量 mBatteryReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final int level = intent.getIntExtra( BatteryManager.EXTRA_LEVEL, -1); Runnable updateBatteryLevel = new Runnable() { @Override public void run() { […]

Android:时间显示

private void initUpdateTimeThread() { Calendar calendar = Calendar.getInstance(); mHour = calendar.get(Calendar.HOUR_OF_DAY); mMinute = calendar.get(Calendar.MINUTE); setTimeString(mHour, mMinute); mUpdateTimeThread = new Runnable() { @Override public void run() { if (++mMinute >= 60) { mMinute = 0; ++mHour; } if (mHour >= 24) { mHour = 0; } setTimeString(mHour, mMinute); mHandle.postDelayed(this, 60000); } […]

重写Android Viewgroup的addView方法

Viewgroup.addView()有5个重载方法: void addView(View child, int index, ViewGroup.LayoutParams params) void addView(View child, ViewGroup.LayoutParams params) void addView(View child, int index) void addView(View child) void addView(View child, int width, int height) 如果需要想重写addView()实际只需要重写addView(View child, int index, ViewGroup.LayoutParams params)即可。 看一下addView的源码: public void addView(View child) { addView(child, -1); } public void addView(View child, int index) { […]

Android OTA升级中的一些零碎知识

OTA升级脚本 build/tools/releasetools recovery-resource.dat # Recovery is generated as a patch using both the boot image # (which contains the same linux kernel as recovery) and the file # /system/etc/recovery-resource.dat (which contains all the images # used in the recovery UI) as sources. This lets us minimize the # size of […]

windows python跨进程访问文件

OS: windows 7 python: 2.7 最近在把Android OTA的整套东西移植到windows上,涉及了很多python脚本,要疯了。暂不说没写过一行python了,就是windows系统也有很多年头没动过了,这个牛X的系统,居然还是那么难用。 问题描述: temp_zip_file = tempfile.NamedTemporaryFile() #同一线程访问temp_zip_file #不同线程访问temp_zip_file temp_zip_file.close() 运行时提示错误: 另一个程序正在使用此文件,进程无法访问。 靠啊,这么简单的一条语句还能出啥问题啊,在Linux上也是没有问题的,查查文档,发现下面这句话: tempfile.NamedTemporaryFile([mode=’w+b'[, bufsize=-1[, suffix=”[, prefix=’tmp'[, dir=None[, delete=True]]]]]]) This function operates exactly as TemporaryFile() does, except that the file is guaranteed to have a visible name in the file system (on Unix, the directory entry […]

Android LinearGradient

Bitmap mBitmap; Matrix mShadowPaint; Matrix mLinearGradientMatrix; LinearGradient mLinearGradient; mBitmap = BitmapFactory.decodeResource(getResource, R.drawable.jobs); mShadowPaint = new Paint(); mShadowPaint.setStyle(Style.FILL); mShadowPaint.setAlpha((int)0.9 * 255); //渐变范围从(0, 0)到(1.0, 0) //渐变颜色从红色到透明 //TileMode.CLAMP重复边缘色,这里实际是拉伸透明 mLinearGradient = new LinearGradient(0, 0, 1.0f, 0, Color.red, Color.TRANSPARENT, TileMode.CLAMP); mLinearGradientMatrix = new Matrix(); mLinearGradientMatrix.setScale(mBitmap.getWidth(), 1); //把线性渐变的范围扩大到整张图片 mLinearGradient.setLocalMatrix(mLinearGradientMatrix); mShadowPaint.setShader(mLinearGradient); canvas.drawBitmap(mBitmap, 0, 0, null); canvas.drawRect(0, 0, […]

Android install HTTP Cache

// > Android 4.0, 向下兼容 private void enableHttpResponseCache() { try { long cacheSize = 10 * 1024 * 1024; File cacheDir = new File(getCacheDir(), “cache”); Class.forName(“android.net.http.HttpResponseCache”) .getMethod(“install”, File.class, long.class) .invoke(null, httpCacheDir, httpCacheSize); } catch (Exception httpResponseCacheNotAvailable) { } }

How to change Kernel Version String

OS: Android 4.4 Kernel: 3.10.28 这里所谓的修改kernel version string并不是真的修改linux的版本号,因为那样会导致非常多的问题(比如一些驱动会不能用,等等)。所以这里修改的仅仅是/proc系统下的version,而从/proc/version中读取kernel version string是一个通常的做法,所以只需要修改这个就可以了。 kernel/fs/proc/version.c static int version_proc_show(struct seq_file *m, void *v) { seq_printf(m, linux_proc_banner, utsname()->sysname, utsname()->release, utsname()->version); return 0; } seq_printf和printf的功能很类似,可以输出经格式化的字符串。这里的linux_proc_banner参数实际上是一个格式化字符串,它的定义在文件kernel/init/version.c中: const char linux_proc_banner[] = “%s version %s” ” (” LINUX_COMPILE_BY “@” LINUX_COMPILE_HOST “)” ” (” LINUX_COMPILER “) %s\n”; 所以很明显你可以通过修改上面2个文件来定制你自己的version string. 接下来看看Android的setttings中是如何来读取kernel version的: […]

Android定制BootAnimation

准备动画图片 把制作好的动画帧图片按播放顺序命名,如 0001.png 0002.png … 0098.png 0099.png,命名可以不连续但是先后顺序一定要正确,Android将以数值升序播放。Tip:如何在Linux下批量重命名 创建父文件夹并命名为animation。 创建子文件夹并命名为part0。 把命名好的图片放到part0中。(PS:我分别测试了PNG和JPG格式的图片,Android都可以正常播放)接着在父文件夹中创建文件desc.txt,这个文件将控制Android如何播放动画。 看一下这个文件的: 800 1280 24 p 0 1 part0 第一行: 800 1280是图片宽高,一般跟手机屏幕的宽高一致。 24指的是播放帧率(帧/s)。 第二行:p标志一条播放规则。0 循环播放本文件中所有图片的次数,值0表示无限循环直到进入系统。1 播放相邻两帧图片之间的间隔时间。part0 对应图片的文件夹。 你可以用相同的方法建立多条播放规则,需要注意的是无限循环规则应该放到最后一条。 如: 800 1280 24 p 1 1 part0 p 1 0 part1 p 0 0 part2 打包 Android bootanimation不支持经过压缩的包,记住一定要只打包不压缩。 cd animation zip -r […]

Android:How to change MTP and PTP name

Android OS: 4.4.4 Sometimes, you want to change the default MTP/PTP name of your android device. If you have android source, it’s very easy. First open the source file: frameworks/base/media/java/android/mtp/MtpDatabase.java, Line:799(in my source), or you can search the function getDeviceProperty private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { switch […]

Framework增加资源文件

把需要增加的图片资源放到 frameworks/base/core/res/res/drawable-nodpi,如果就这样直接应用这个资源,会出现找不到资源的错误。实际上在增加完资源后还需要在 frameworks/base/core/res/res/values/symbols.xml文件中做相应的注册,比如: <java-symbol type=”drawable” name=”my_wallpaper” /> 重新编译framework-res后就可以使用这个资源了: com.android.internal.R.drawable.my_wallpaper

Android设置系统首次开机的默认输入法

Android OS: 4.4.4 需求:Android系统首次开机(恢复出厂状态),读取build.prop中的属性来设置默认的输入法。 增加系统属性 ro.product.IME.default 修改InputMethodService 打开文件 frameworks/base/services/java/com/android/server/InputMethodManagerService.java 增加如下方法: /** * 0: not first boot * 1: first boot */ static final String FIRST_BOOT_FLAG = “first_boot_flag”; private void setCustomDefaultIME() { int firstBootFlag = Settings.System.getInt( mContext.getContentResolver(), FIRST_BOOT_FLAG, 1); if(DEBUG) Slog.d(TAG, “First Boot Flag: ” + firstBootFlag); if (1 == firstBootFlag) […]