Menu Home

VirtualBox使用摄像头

OS: OSX 10.10.1 VirtualBOX: 4.3.20 近期在OSX上使用VirtualBox安装了一个Win7用来测试一个摄像头程序,但是发现VirtualBox本身是不支持使用HOST机的摄像头设备的,需要VirtualBox Extension Pack的支持才可以。 可以在这里下载对应ViretualBox版本的ExtensionPack,点击安装成功后,可以看到如下界面: 进入系统后即可在Devices -> Webcams中找到你的视频设备。

关于图片Drawable的宽高

在Android项目的res目录下有一些对应不同屏幕DPI的子文件夹: 分别对应的DPI为: ldpi (low) ~120dpi mdpi (medium) ~160dpi hdpi (high) ~240dpi xhdpi (extra-high) ~320dpi xxhdpi (extra-extra-high) ~480dpi 为什么要分这些文件夹呢? 为了能够自动适配不同的屏幕,使他们看上去大小(基本)一致。 我们可以使用一张分辨率为500×500的图片(test.jpg)做一些测试。 测试代码片段如下: public class MainActivity extends Activity { TextView tv; ImageView img; Drawable drawable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img = (ImageView)findViewById(R.id.img); tv = (TextView)findViewById(R.id.tv); drawable = getResources().getDrawable(R.drawable.test); […]

Android多窗口分屏(原生方法)

事实上KitKat已经可以实现多窗口分屏,只是功能不全,Google并没有把这个功能提供给用户。 使用am stack boxes可以查看当前系统存在的Activity Stack: am stack boxes output: Box id=1 weight=0.0 vertical=false bounds=[0,38][800,1208] Stack= Stack id=1 bounds=[0,38][800,1208] taskId=2: com.android.calendar/com.android.calendar.AllInOneActivity taskId=3: com.android.deskclock/com.android.deskclock.DeskClock Box id=0 weight=0.0 vertical=false bounds=[0,38][800,1208] Stack= Stack id=0 bounds=[0,38][800,1208] taskId=1: net.lnmcc.launcher/net.lnmcc.launcher.Launcher 从上面的输出我们看到当前有两个Stack,id分别为0和1。在Stack 1中存在了两个Task,这两个Task分别是Calender和DeskClock应用。而Launcher则是在Stack 0中。实际上,你会发现Launcher始终独占Stack 0。Android有如下规则: HOME stack: This is the stack with id = 0. This stack is […]

Android电源管理-Healthd (2)

接上文 Android电源管理-Healthd (1) adb shell进入到/sys/class/power_supply目录,我们可以看到power_supply驱动创建的一些运行时文件(我的设备是Nuxus 7, Android 4.4.2, kernel 3.4.0): adb root adb shell cd /sys/class/power_supply ll 输出如下: lrwxrwxrwx root root 2014-09-19 14:30 ac -> ../../devices/i2c-0/0-0055/power_supply/ac lrwxrwxrwx root root 2014-09-19 14:30 battery -> ../../devices/i2c-0/0-0055/power_supply/battery lrwxrwxrwx root root 2014-09-19 14:30 usb -> ../../devices/i2c-0/0-0055/power_supply/usb lrwxrwxrwx root root 2014-09-19 14:30 wireless -> ../../devices/i2c-0/0-0055/power_supply/wireless […]

Android控制生成ODEX

如果没有指定DISABLE_DEXPREOPT,那么user版将生成odex,其他版本不会生成odex文件。 相关文件在build/core/main.mk ifneq (true,$(DISABLE_DEXPREOPT)) ifeq ($(user_variant),user) ifeq ($(HOST_OS),linux) WITH_DEXPREOPT := true endif endif endif 如果user版不想生成odex,那么需要定义 DISABLE_DEXPREOPT := true 如果eng版要生成odex,那么需要定义 WITH_DEXPREOPT := true 如果想单独控制某一应用是否生成odex,可以在应用的Android.mk中定义 WITH_DEXPREOPT := true

Android电源管理-Healthd (1)

OS:Android 4.4.2 Android电源管理底层用的是Linux power supply框架。驱动部分不叙述。只看JAVA、JNI和CPP应用层。 从Android 4.4开始,Google专门提供了一个healthd来监控电源状态。它的路径在:system/core/healthd,编译出来的文件为/sbin/healthd。 看一下healthd.cpp中的main函数: int main(int argc, char **argv) { int ch; klog_set_level(KLOG_LEVEL); while ((ch = getopt(argc, argv, “n”)) != -1) { switch (ch) { case ‘n’: nosvcmgr = true; break; case ‘?’: default: KLOG_WARNING(LOG_TAG, “Unrecognized healthd option: %c\n”, ch); } } healthd_board_init(&healthd_config); wakealarm_init(); uevent_init(); binder_init(); […]

px、dp、sp转换

public class DensityUtil { public static int px2dp(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } public static int dp2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } public static int px2sp(Context […]

Android触摸事件处理流程

在Android中,所谓消费了一个touch事件均以返回值的真假来确定。true = 已消费;false = 未消费 Activity.dispatchTouchEvent 一个touch事件首先会交给Activity.dispatchTouchEvent()进行分发给Activity的根View。当没有任何一个子View消费掉这个事件的时候,这个事件会交给Activity.onTouchEvent()来处理。 当Activity.dispatchTouchEvent()返回true,意味屏蔽了所有的touch事件。 dispatchTouchEvent()的处理流程代码: public boolean dispatchTouchEvent(MotionEvent ev) { if(!onInterceptTouchEvent()){ for(View child : children){ if(child.dispatchTouchEvent(ev)) return true; } } return super.dispatchTouchEvent(ev); } ViewGroup.onInterceptTouchEvent一个完整的touch事件是指从ACTION_DOWN到ACTION_UP/ACTION_CANCEL,之间可能包括许多ACTION_MOVE。其中ACTION_DOWN是一个开始事件也是最重要的一个事件,是否处理ACTION_DOWN会直接影响到其是否能接受到后续事件。 当ViewGroup的onInterceptTouchEvent()返回true时,其目标子view会接受到ACTION_CANCEL事件,其表明目标子View将不再接受后续的所有touch事件,而后续的touch事件都将交由ViewGroup的onTouchEvent()来处理。 当ViewGroup的onInterceptTouchEvent()返回false时,那么这个事件不会交给本ViewGroup的onTouchEvent()处理,而是往下传递。 ViewGroup提供了一个requestDisallowInterceptTouchEvent(boolen),它的作用是当某个子View不希望它的父ViewGroup和祖先ViewGroup通过onInterceptTouchEvent()截获touch事件时,给这个方法传递true 。 当没有子View消费掉touch event时,ViewGroup.onTouchEvent()将被调用。 View.onTouchEvent 如果View想处理一个Touch Event,那么它必须处理ACTION_DOWN事件,否则将接收不到任何后续事件。 当onTouchEvent返回true,意味着这个事件被消费掉了,false则会将该事件上传到ViewGroup的onTouchEvent()来处理。

Git: 工作区、暂存区和分支区

当我们建立了一个git库的时候,实际上我们就拥有了3棵目录树,分别是:工作区、暂存区和分支区。 工作区 工作区就是你项目的当前目录。 暂存区 暂存区是Git跟其他版本控制工具(CVS、SVN)最大的一个区别,是Git独有的。 当你使用 git add 的时候,实际上只是把工作区中的文件放到了暂存区中,在你的版本库中还没有你的文件,只有在你使用 git commit 后,才真正把你的文件提交到了版本库中。 分支区 分支区是真正用来管理你项目文件的地方。在新建的git库中自动会产生一个master分支,而HEAD即是指向这个master分支的游标。 如何查看各区域的目录树 查看工作目录 要查看工作目录中的目录树是最简单的,跟git根本没有关系,直接 ls -l 查看暂存区目录树 git write-tree | xargs git ls-tree 查看master分支目录树 git ls-tree HEAD 这里的HEAD指向master分支。 如果想查看子目录下的内容,跟linux的ls一样,可以加上-r参数。 git ls-tree -r HEAD

在FrameLayout中使用marginBottom

想把一个控件放到FrameLayout的底部位置,尝试了好久layout_marginBottom属性,居然毫无作用。但是layout_marginTop又是可以正确显示的。 现象如下: <FrameLayout android:layout_width=”match_parent” android:layout_height=”match_parent” > <TextView android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginBottom=”50dp” android:text=”This text should be at bottom” android:textSize=”20dp” /> </FrameLayout> 显示如下图(错误): <FrameLayout android:layout_width=”match_parent” android:layout_height=”match_parent” > <TextView android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginTop=”50dp” android:text=”This text should be at bottom” android:textSize=”20dp” /> </FrameLayout> 显示如下图(正确): 解决方案: 需要在做layout_marginBottom前设置layout_gravity为bottom <FrameLayout android:layout_width=”match_parent” android:layout_height=”match_parent” > <TextView android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_gravity=”bottom” android:layout_marginBottom=”50dp” android:text=”This […]

Android:获取内存和进程信息

ActivityManager mAm = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); private int getAppsRunning() { List<RunningAppProcessInfo> runningApps = mAm.getRunningAppProcesses(); return runningApps.size(); } private long getFreeMemory() { MemoryInfo mi = new MemoryInfo(); mAm.getMemoryInfo(mi); return mi.availMem; }

Android:  位置更新最佳实践

监测所选位置提供器的状态,当其不可用时,动态切换到一个新的提供器,当有更适合的提供器可用时,切换到这个更适合的位置提供器。 private void unregisterAllListeners() { locationManager.removeUpdates(bestProviderListener); locationManager.removeUpdates(bestAvailableProviderListener); } private void registerListener() { unregisterAllListeners(); String bestProvider = locationManager.getBestProvider(criteria, false); String bestAvailableProvider = locationManager.getBestProvider(criteria, true); if(bestProvider == null) { Log.d(TAG, “No Location Provider exist on device”); } else if(bestProvider.equals(bestAvailableProvider)) { locationManager.requestLocationUpdates(bestAvailableProvider, minTime, minDistance, bestAvailableProviderListener); } else { locationManager.requestLocationUpdates(bestProvider, minUpdateTime, minUpdateDistance, bestProviderListener); } […]

反编译Android APK

呃~~~ 反编译一般都是作学习用的-_-# OS:Android 4.4.2 HOST: OS X 需要的工具 baksmali / smali: 把odex转换成dex dex2jar: 把dex转换成jar jd-gui: 反编译jar 具体步骤 这里我尝试反编译SystemUI,先使用adb pull把SystemUI.apk和SystemUI.odex从手机中取出到本地的tmp目录中(什么是odex可以google一下)。 整个反编译的过程如下: odex —-> dex —-> jar —-> java odex —-> dex java -jar baksmali-2.0.3.jar -a 19 -x SystemUI.odex -d . 参数说明: -a : API Level, 这里4.4.2的API Level为19 -x : 反编译 -d […]