Android 收银机开发笔记

Summer Wind

前言:记录下自己在收银机开发过程中的一些心得笔记,此博客长期更新。

00 收银机开发和普通安卓手机应用开发的区别

个人觉得,最大的区别就是,屏幕空间变大了,一屏之内可展示的内容变多了。其实不仅仅是屏幕空间变大了,也由原来的习惯看竖屏到习惯看横屏了。另外需要做的适配工作也简单很多,因为收银机屏幕分辨率和屏幕大小都差不多,几乎不需要做特殊的适配,而且你甚至可以更改屏幕密度!下面会说到。

还有一点就是,不再需要担心应用保活的问题了,因为基本上安装到商家的收银机上之后,我们的应用就是主角,所以可供我们发挥的空间就大了。另外诸如开机自启、系统敏感权限等,这些都不是事儿~

虽然少了很多限制,但还是想说,安全对一款收银机应用来说还是非常重要的,比如怎样保证应用的数据安全以及网络安全,这些都是目前还没来得及做、未来需要完善的。

01 应用全屏

PART 1

一般来说,我们的收银机应用大多数时候都应该占满屏幕,所以需要用到全屏模式:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowAnimationStyle">@style/notAnimation</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

可以看到我们使用了 Theme.AppCompat.Light.NoActionBar 作为父主题,然后覆盖了 android:windowFullscreenandroid:windowContentOverlay 属性,前者用于隐藏状态栏,后者用于消除包裹应用 content 的 drawable(通常是标题下的阴影),参考 windowContentOverlay

PART 2

当然,这些只是最基本的,我们还需要处理 activity 配置发生改变的情况,在 activity 下添加:

android:configChanges="orientation|screenSize|keyboardHidden"

这样,我们就告诉系统当 activity 屏幕方向或者键盘可见性发生变化后不要退出重启 activity,因为收银机应用几乎所有 activity 屏幕方向都应该是水平的。

另外关于键盘,还需要在 activity 中加上 android:windowSoftInputMode="stateHidden|adjustPan" 属性,stateHidden 表明当用户初次进入 activity 的时候,键盘不会显示出来(一般只有在登录界面才会需要键盘一开始就显示),而 adjustPan 则会在键盘显示出来的时候自动调整 UI 内容,让用户始终可以看到他们输入的内容而不是被键盘覆盖掉。

所以 AndroidManifest 中我们的 activity 大多数是这样配置的:

<activity
    android:configChanges="orientation|keyboardHidden|screenSize"
    android:screenOrientation="landscape"
    android:windowSoftInputMode="stateHidden|adjustPan" />

具体参数介绍请看 <activity>

PART 3

这些就够了吗?当然不是!通常,我们还需要在我们的 BaseActivity 中做如下配置:

//开启全屏
final int fullScreenFlags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_FULLSCREEN //hide statusBar
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //hide navigationBar
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

final Window window = getWindow();
window.getDecorView().setSystemUiVisibility(fullScreenFlags);
window.getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
    @Override
    public void onSystemUiVisibilityChange(int visibility) {
        window.getDecorView().setSystemUiVisibility(fullScreenFlags);
    }
});

可以看到我们给 DecorView 设置了一些 Visibility 的 Flag, 首先是隐藏状态栏和导航栏,然后是 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 用于沉浸模式,也就是使状态栏变得半透明,同时接受屏幕边缘的滑动事件(通常这类事件是由系统处理掉的)。文档上是这么写的:

While in sticky immersive mode, if the user swipes from an edge with a system bar, system bars appear but they're semi-transparent, and the touch gesture is passed to your app so it app can also respond to the gesture.

然后是 View.SYSTEM_UI_FLAG_LAYOUT_STABLE 用于保证你的布局全屏,不会因为系统栏的显示而重新调整大小。具体请参考文档:Enable fullscreen mode

PART 4

除此之外,我们还应该考虑到一些特殊情况,比如显示 dialog 或者用户输入的情况下,这些时候导航栏都会显示出来,所以通常我们还会写这么一个方法:

public void enterFullScreen(Window window) {
    window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
    int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        | View.SYSTEM_UI_FLAG_FULLSCREEN;
    window.getDecorView().setSystemUiVisibility(uiOptions);
}

然后在显示 dialog 或者其他一些有可能触发导航栏显示的地方调用下这个方法,这样就能保证始终全屏啦。另外对于监听键盘输入,推荐一个三方库:KeyboardVisibilityEvent,使用起来非常方便,只要在 activity 初始化的地方调用:

KeyboardVisibilityEvent.setEventListener(this,
    new KeyboardVisibilityEventListener() {
        @Override
        public void onVisibilityChanged(boolean isOpen) {
            UIHelper.create().enterFullScreen(getWindow());
        }
});

这样当用户使用键盘输入的时候,我们可以保证始终全屏显示。

最后,也许有人会有疑问,如果我们的应用开机自启,而且始终全屏,那不是无法回到桌面了吗?其实不用担心,我们可以自己设置一个按钮,提供回到桌面的功能,比如当用户点击右下角显示当前时间的地方。是不是听起来有点熟悉?没错,就是受到了 windows 的启发~ ʘ‿ʘ

02 修改收银机主屏幕密度

PART 1

首先说明下,这种方式只针对使用瑞芯芯片的收银机才有效,可以用以下命令检查是否是支持修改:

adb shell cat /system/build.prop | grep ro.sf.lcd_density
# or
adb shell getprop ro.sf.lcd_density

如果存在该属性则证明可以修改。下面是步骤(过时,参考 PART 3):

  1. /system/build.prop 文件拉到本地,使用 adb 命令:
adb pull /system/build.prop ./
  1. 打开 build.prop 文件,找到 ro.sf.lcd_density 属性,这个属性就是用来指定屏幕密度的,直接修改成我们想要的密度就可以了,默认是 160,我们可以修改为 240。个人觉得,对于一般收银机来说,这是看着最舒服的:
# set default lcd density to Rockchip tablet
ro.sf.lcd_density=240
  1. 将修改完毕后的文件覆盖掉原文件,当然首先要将 /system 挂载为可读写再覆盖:
adb root
adb shell mount -o rw,remount /system
adb push build.prop /system/
  1. 最后不要忘记修改 /system 为只读:
adb shell mount -o ro,remount /system
adb shell reboot

最后,当机子重启完毕,新的屏幕密度就已经起作用了。

PART 2

当然,上面这些步骤对于安卓开发来说没难度,但是对于运维来说,其实还是挺麻烦的,所以写了个 batch 脚本(运维用Windows -_-||),只要用数据线连接上收银机,双击运行下就ok了,我是不是很棒~

Github 地址:ChangeDensity-win-batch

PART 3

其实修改屏幕分辨率还有一个更简便的方法,那就是通过 adb 命令中的 Window Manager,一行命令就可以搞定:

adb shell wm density [reset|DENSITY] 

参数中 reset 表示恢复默认值,DENSITY 就是你想要修改成的屏幕密度,是不是异常简单?而且这种修改方式是立即生效的,和之前的方法一比简直不要太方便。同样只要检查 ro.sf.lcd_density 参数是否存在就可以了。另外,wm 全部命令如下:

usage: wm [subcommand] [options]
       wm size [reset|WxH|WdpxHdp]
       wm density [reset|DENSITY]
       wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]
       wm scaling [off|auto]
       wm screen-capture [userId] [true|false]

wm size: return or override display size.
         width and height in pixels unless suffixed with 'dp'.

wm density: override display density.

wm overscan: set overscan area for display.

wm scaling: set display scaling mode.

wm screen-capture: enable/disable screen capture.

wm dismiss-keyguard: dismiss the keyguard, prompting the user for auth if necessary.

wm surface-trace: log surface commands to stdout in a binary format.

可以看到屏幕分辨率也是可以直接修改的:

adb shell wm size [reset|WxH|WdpxHdp]

新技能 GET! (•̀ᴗ•́)و ̑̑


喜欢我的文章就用你最喜欢的手指点个赞吧~ (づ ̄3 ̄)づ╭❤~

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 1回放我在事件当中是什么样的情绪? 情绪: 事件:今天去开家长会,听老师说他们班这次文艺会员,很多同学都展示了自己...
    胡傲宣阅读 106评论 0 0
  • 这学期学习的一个新课程是产品摄影,因为之前学习的一直是拍摄的是商业人像,所以对产品摄影这方面比较陌生。 老师在...
    鱼三秒阅读 639评论 2 7
  • 你们好!我第一次写小说、中学毕业并没有什么文采,这篇小说我不是要演绎些什么。我只是想把我这四年的经历和爱情故事分享...
    感博主阅读 521评论 0 0
  • 高一 高一下学期刚开学。 我总盯着教室外的花坛里那株正盛开的绿色梅花,秃秃的枝桠和略显浓密的花。枝很累吧?托着花朵...
    温心一阅读 298评论 0 0