Android命令行下运行JAVA程序之StatusBar控制

最近在思索着Android命令行下可以执行C语言写的命令行程序(Android是基于Linux的,那么Linux支持的,在Android上也是支持的),那么Android上层基于JAVA的Dalvik虚拟机是否也可以让JAVA程序在命令行下执行,答案是肯定的,我们发现在Android源码目录下的frameworks/base/cmds/目录下有相应的程序,可将普通的JAVA程序打包成JAR,让其运行于Dalvik虚拟机上,而不是标准的JVM上。为了对其研究实践一番,编写了如下例子:

Android4.0状态栏控制命令:基于Android4.0.4系统,需要在源码环境下编译(即需要有Android源码和编译环境),实现功能有:

1、控制整个状态栏的显示、隐藏;

2、控制BACK、HOME、RECENT这三个按键的显示、隐藏;

首先,我们在Android源码目录下的frameworks/base/cmds目录下创建sbstate目录(StatusBarState),该目录下包含Android.mk、sbstate两文件和src目录,其中src目录下包含了整个JAVA包的层级目录及类源码,其路径结构为src/com/cmds/xinu/Sbstate.java。

Sbstate.java源码如下:

package com.cmds.xinu;

import android.content.Context;

import android.os.ServiceManager;

import android.os.RemoteException;

import android.view.View;

import com.android.internal.statusbar.IStatusBarService;

public class Sbstate {

public static void main(String[] args) {

(new Sbstate()).run(args);

}

private void run(String[] args){

if (args.length < 1){

showUsage();

return;

}

String command = args[0];

IStatusBarService mBarService;

mBarService = IStatusBarService.Stub.asInterface(

ServiceManager.getService(Context.STATUS_BAR_SERVICE));

if (command.equals("sbvis")){

try {

mBarService.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);//View.STATUS_BAR_VISIBLE

} catch (RemoteException ex) {

}

System.out.println("Status Bar Visible!");

} else if (command.equals("sbdis")){

try {

mBarService.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);//View.STATUS_BAR_HIDDEN

} catch (RemoteException ex) {

}

System.out.println("Status Bar Disable/Unvisible!");

} else if (command.equals("bvis")){

try{

mBarService.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE & ~View.STATUS_BAR_DISABLE_BACK);

} catch (RemoteException ex) {

}

System.out.println("Back button visible!");

} else if (command.equals("bdis")){

try{

mBarService.setSystemUiVisibility(View.STATUS_BAR_DISABLE_BACK);

} catch (RemoteException ex) {

}

System.out.println("Back button Disable/Unvisible!");

} else if (command.equals("hvis")){

try{

mBarService.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE & ~View.STATUS_BAR_DISABLE_HOME);

} catch (RemoteException ex) {

}

System.out.println("Home button visible!");

} else if (command.equals("hdis")){

try{

mBarService.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);

} catch (RemoteException ex) {

}

System.out.println("Home button Disable/Unvisible!");

} else if (command.equals("rvis")){

try{

mBarService.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE & ~View.STATUS_BAR_DISABLE_RECENT);

} catch (RemoteException ex) {

}

System.out.println("Recent button visible!");

} else if (command.equals("rdis")){

try{

mBarService.setSystemUiVisibility(View.STATUS_BAR_DISABLE_RECENT);

} catch (RemoteException ex) {

}

System.out.println("Recent button Disable/Unvisible!");

}

}

private void showUsage(){

System.err.println("Usage:sbstate [sbvis|sbdis|bvis|bdis|hvis|hdis|rvis|rdis]");

System.err.println("      sbvis:statusbar visible");

System.err.println("      sbdis:statusbar disable");

System.err.println("      bvis:back button visible");

System.err.println("      bdis:back button disable");

System.err.println("      hvis:home button visible");

System.err.println("      hdis:home button disable");

System.err.println("      rvis:recent button visible");

System.err.println("      rdis:recent button disable");

}

}

该部分源码都是调用Android的API,之前一直犯难的是在如何获取StatusBar相关对象,后来查看了cmds目录下的其他文件,发现基本上是通过调用Interface来获取实例,其他都是标准的JAVA语言代码。

sbstate文件内容如下:

base=/system

export CLASSPATH=$base/framework/sbstate.jar

exec app_process $base/bin com.cmds.xinu.Sbstate $*

该部分内容主要是设置CLASSPATH环境变量为我们编译出来的JAR文件,即指定了我们的程序位置,Android源码编译完后会放至/system/framework目录下,接下来使用Linux命令下的exec命令来调用app_process命令执行我们的JAVA程序,其中app_process命令位于源码目录下的frameworks/base/cmds/app_process目录下,其命令的使用方法如下:

Usage: app_process [java-options] cmd-dir start-class-name [options]

其中我们文件里的$base/bin对应的是命令所在的目录,com.cmds.xinu.Sbstate为我们的JAVA代码的入口类,即main函数所在的类名,而$*是将命令行输入的任何参数传递作为main函数的参数列表。

Android.mk文件内容:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_MODULE := sbstate

include $(BUILD_JAVA_LIBRARY)

include $(CLEAR_VARS)

ALL_PREBUILT += $(TARGET_OUT)/bin/sbstate

$(TARGET_OUT)/bin/sbstate : $(LOCAL_PATH)/sbstate | $(ACP)

$(transform-prebuilt-to-target)

其中文件是参考其他同目录下的Android.mk文件,其功能主要是将JAVA文件编译成JAVA库JAR文件,并把sbstate文件复制到目标目录的system/bin目录下,我这边测试时是手动把sbstate文件复制到/system/bin目录下,此时需要注意该文件的权限,不然会有Permission Deny之类的提示。

由于我们放在源码里编译,如果直接这样mm一下,是会出错的,我们还需要修改Android源码的编译配置,涉及到如下文件:

1、build/core/legacy_prebuilts.mk

对应于Android.mk里要用到的prebuilt功能,主要是把sbstate文件复制到/system/bin目录下,不加的话会提示预编译失败;

在文件中修改GRANDFATHERED_ALL_PREBUILT配置项,添加上sbstate。

2、build/core/user_tags.mk

对应于Android.mk里要用到的编译为JAR功能,在文件中修改GRANDFATHERED_USER_MODULES配置项,添加上sbstate。

至此,整个编译配置及源码就实现好了,接下来只需要mm一下,复制或者烧录一下,就可以在命令行(串口或者ADB)下大胆的敲上sbstate命令,会有如下提示:

Usage:sbstate [sbvis|sbdis|bvis|bdis|hvis|hdis|rvis|rdis]

sbvis:statusbar visible

sbdis:statusbar disable

bvis:back button visible

bdis:back button disable

hvis:home button visible

hdis:home button disable

rvis:recent button visible

rdis:recent button disable

此时,我们可以输入如下形式的命令来执行相应的功能:

1、显示状态栏:sbstate sbvis

2、隐藏状态栏:sbstate sbdis

3、显示BACK按钮图标:sbstate bvis

4、隐藏BACK按钮图标:sbstate bdis

5、显示HOME按钮图标:sbstate hvis

6、隐藏HOME按钮图标:sbstate hdis

7、显示RECENT按钮图标:sbstate rvis

8、隐藏RECENT按钮图标:sbstate rdis

好了,亲手尝试一下吧,见证状态栏的风起云涌,变幻莫测吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容