在很多时候,我们需要在代码中实现这样的功能:某个功能只对特殊的应用生效,那么就需要在代码中实现获取当前应用包名的功能。这里使用的是属性传递包名的方法。具体就是在应用加载启动的时候,将获取到的包名写入到属性当中,然后在需要特殊处理的代码位置通过检查该属性即可获取到当前的应用,即可达到目的。
获取并设置当前应用包名
在android中同一时间可能会加载和运行很多程序应用,那么如何获取或确定当前运行的应用是哪个呢?在android的窗口管理中,也是就windowManagerService中,有个很重要的接口用于设置当前聚焦的应用,这个接口就是setFocusedApp。在打开或者切换到某个应用时,android系统需要更新当前聚焦的应用,也就需要通过setFocusedApp设置新的聚焦。我们就可以通过该接口来获取当前的应用包名,并实时更新。代码如下所示:
+import android.os.SystemProperties;
...
boolean setFocusedApp(ActivityRecord newFocus) {
if (newFocus != null) {
final DisplayContent appDisplay = newFocus.getDisplayContent();
if (appDisplay != this) {
throw new IllegalStateException(newFocus + " is not on " + getName()
+ " but " + ((appDisplay != null) ? appDisplay.getName() : "none"));
}
// Called even if the focused app is not changed in case the app is moved to a different
// TaskDisplayArea.
onLastFocusedTaskDisplayAreaChanged(newFocus.getDisplayArea());
}
if (mFocusedApp == newFocus) {
return false;
}
ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "setFocusedApp %s displayId=%d Callers=%s",
newFocus, getDisplayId(), Debug.getCallers(4));
mFocusedApp = newFocus;
getInputMonitor().setFocusedAppLw(newFocus);
updateTouchExcludeRegion();
+ if(newFocus != null)
+ SystemProperties.set("sys.focuse_app.name",newFocus.packageName);
return true;
}
获取属性值
在上述代码中,已经将当前聚焦应用的包名设置到属性“sys.focuse_app.name”中了,那么在任意可以正常使用属性的代码中,即可通过获取属性的标准接口如property_get 来获取当前的包名,即可实现差异化的功能。例如在C中实现只对youtube应用的差异化操作,代码如下所示:
+ #include <cutils/properties.h>
...
+ char focusapp[256];
+ property_get("sys.focuse_app.name",focusapp, "");
+ if(strstr("com.google.android.youtube", focusapp) != NULL)
+ {
+ printf("focusapp '%s' ,do something special.\n",focusapp);
+ //TODO
}