美文网首页Android开发经验谈Android开发Android技术知识
Android命令行下运行JAVA程序之StatusBar控制

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

作者: 网路元素 | 来源:发表于2017-09-10 11:52 被阅读98次

    最近在思索着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

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

    相关文章

      网友评论

        本文标题:Android命令行下运行JAVA程序之StatusBar控制

        本文链接:https://www.haomeiwen.com/subject/ycbzjxtx.html