22 Jun 2014
监测所选位置提供器的状态,当其不可用时,动态切换到一个新的提供器,当有更适合的提供器可用时,切换到这个更适合的位置提供器
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);
}
if(bestAvailableProvider != null) {
locationManager.requestLocationUpdates(bestAvailableProvider, minTime, minDistance, bestAvailableProviderListener);
} else {
List<String> allProviders = locationManager.getAllProviders();
for(String provider : allProviders)
locationManager.requestLocationUpdates(provider, minTime, minDistance, bestProviderListener);
Log.d(TAG, "No Location Providers currently available.");
}
}
private LocationListener bestProviderListener = new LocationListener() {
@Override
public void onProviderEnabled(String provider) {
registerListener();
}
}
private LocationListener bestAvailableProviderListener = new LocationListener() {
@Override
public void onProviderEnabled(String provider) {
registerListener();
}
}
ref: 《Android 4高级编程》 p.474
22 Jun 2014
呃~~~ 反编译一般都是作学习用的-_-#
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 : 依赖包目录
上面的命令会产生错误,是因为缺少依赖包,可以根据错误信息一次从手机中把依赖包pull到本地目录中。
当所以依赖都完整后,上面的命令会生成一个out文件夹,可以通过这些文件来生成dex。
java -jar smali-2.0.3.jar -a 19 -o SystemUI.dex out
如果上面的命令执行成功,那么现在目录中就有了SystemUI.dex。
-
dex —-> jar
d2j-dex2jar.sh SystemUI.dex
上面的命令完成后会生成SystemUI-dex2jar.jar,最后就差使用JD-GUI来查看java文件了。
-
jar —-> java
安装正确的JD-GUI,打开上面生成的SystemUI-dex2jar.jar。

21 Jun 2014
OS: Linux
- 下载ext4_utils: make
- simg2img system.img system.img.ext4
- mount -o loop -t ext4 system.img.ext4 /mnt
ext4_utils
19 Jun 2014
OS: Android 4.4.2
在framework层使用Native lib和在application层的使用有所不同,主要集中在如何正确书写Android.mk和各种依赖关系,要比直接ndk-build麻烦一些。
场景: 在SystemUI包中添加一个Native库,假设名字为libxx.so
处理步骤:
-
进到frameworks/base/packages/SystemUI
下创建JNI文件夹,这里存放所有libxx.so需要的文件。
假设源文件名为xx.c。建立Android.mk文件,文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDFLAGS := -llog -ljnigraphics
LOCAL_MODULE := libxx
LOCAL_SRC_FILES := xx.c
LOCAL_CFLAGS = -ffast-math -O3 -funroll-loops
ifeq ($(TARGET_ARCH), arm)
LOCAL_SDK_VERSION := 9
endif
ifeq ($(TARGET_ARCH), x86)
LOCAL_SDK_VERSION := 9
endif
ifeq ($(TARGET_ARCH), mips)
LOCAL_SDK_VERSION := 9
endif
include $(BUILD_SHARED_LIBRARY)
注意,如果要将libxx.so文件编译到system image,需要修改LOCAL_MODULE_TAGS(如果有),这个值必须为user,而不是samples,或者干脆去掉这个变量 。因为如果没有指定LOCAL_MODULE_TAGS,该项默认为user
-
为了能在编译SystemUI的时候自动编译libxx.so,需要在SystemUI的Android.mk文件中加入如下内容:
ifneq (,$(TARGET_BUILD_APPS))
LOCAL_JNI_SHARED_LIBRARIES := libxx
else
LOCAL_REQUIRED_MODULES := libxx
endif
Android对上面语句的解释如下:
If this is an unbundled build (to install seprately) then include
the libraries in the APK, otherwise just put them in /system/lib and
leave them out of the APK
-
可以用make systemimage和mm SystemUI来测试效果。
19 Jun 2014
Android Framework中的WindowManagerService提供了获取历史Application截图的方法getTaskTopThumbnail,下面演示的只获取了最近一个app的Thumbnail。需要注意的是framework只提供了缩略图,没有提供完整的截图,但是我们可以通过在WindowManagerService中修改getTaskTopThumbnail来提供完整的Application截图。
另:这个方法只能截取Window属性为TYPE_APPLICATION的窗口,对于像属性为TYPE_KEYGUARD等窗口不能使用这个方法,可以通过Surface来截图。
这种方法的意义在于:
你可以获取一个处于pause或stop(可能被另一个窗口遮挡)状态的avtivity的截图,而使用Surface截图只能获取当前显示的画面(也就是framebuffer中的内容)。
ActivityManager am = (ActivityManager) getContext().getSystemService(
Context.ACTIVITY_SERVICE);
private Bitmap takeScreenshot() {
Bitmap bmp = null;
final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasksForUser(
1, ActivityManager.RECENT_IGNORE_UNAVAILABLE,
UserHandle.CURRENT.getIdentifier());
if (recentTasks.size() > 0) {
ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(0);
bmp = am.getTaskTopThumbnail(recentInfo.persistentId);
}
return bmp;
}
ref: frameworks/base/services/java/com/android/server/wm/WindowManagerService.java