一、获取商米设备标识
商米建议通过获取到以下内容来判断是否商米设备:
1.设备的品牌名 brand(如:SUNMI)
商米的品牌名统一为 SUNMI
2.设备的系统型号 model(如:V1-B18)
系统型号组成为 产品型号+硬件特性+‘-’+软件特性
其中以V、M、P、L开头为手持设备,以T、D、S开头为横屏设备(截至2017年12月)
3.设备的ROM版本号(如:1.1.0)。
4.设备的ROM顺序号(如:128)。
可以下载Demo,仿照Demo在自己项目src下面新建android.os包(固定写法),将SystemProperties.java放入该包下,按以下方法获取指定的值:
获取brand的代码为:
String brand = SystemProperties.get("ro.product.brand");
获取model的方法为:
String model = SystemProperties.get("ro.product.model");
获取ROM版本号的代码为:
String versionname = SystemProperties.get("ro.version.sunmi_versionname");
获取ROM顺序号的方法为:
String versioncode = SystemProperties.get("ro.version.sunmi_versioncode");
二、获取设备的SN号
1.在AndroidManifest.xml中添加如下权限。
2.在需要的地方用以下代码获取商米SN号。
try {
Class c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
Log.i("sunmi", "the sn:" + (String) get.invoke(c, "ro.serialno")));
Log.i("sunmi", "First four characters:"
+ (String) get.invoke(c, "ro.serialno").substring(0, 4));
} catch (Exception e) {
e.printStackTrace();
}
3.在需要的地方用以下代码获取客户SN号,限定最多16位数字或大小写字母。(当前仅P1设备支持)
try {
Class c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
Log.i("sunmi", "the customer sn:"
+ (String) get.invoke(c, "gsm.serial1")));
} catch (Exception e) {
e.printStackTrace();
}
三、隐藏及恢复底部导航栏
(注:商米新开发了Kiosk霸屏模式,APP不用做任何修改,仅通过云端设置即可实现隐藏状态栏、导航栏并无法通过手势唤出。 该功能在T2、K1设备上已实现,其他设备上线进展请联系技术支持400-902-1168(9:00-21:00)。 建议合作伙伴使用商米Kiosk霸屏模式,已获得更好的体验)
Android系统默认提供了隐藏系统的导航栏的方法,但对于Dialog的支持较差,导致全屏对话框打开时先弹出导航栏再隐藏(闪屏),SunmiOS针对此问题进行了修复(V1系统固件版本252后支持,T1系统固件版本132后支持)
1.Activity的全屏化
——安卓默认支持
public class MainActivity extends AppCompatActivity {
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
SystemUIUtils.setStickFullScreen(getWindow().getDecorView());
}
}
public class SystemUIUtils {
public static void setStickFullScreen(View view) {
int systemUiVisibility = view.getSystemUiVisibility();
int flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
systemUiVisibility |= flags;
view.setSystemUiVisibility(systemUiVisibility);
}
}
2.Dialog的全屏化
——原生系统下 AOSP 的Bug会导致全屏对话框打开时先弹出导航栏然后再隐藏导航栏(闪屏)。
public AlertDialog create(boolean fullscreen) {
LayoutInflater inflater = LayoutInflater.from(context);
final AlertDialog dialog = new AlertDialog(context,
R.style.DialogStyle);
if(fullscreen){
SystemUIUtils.setStickFullScreen(dialog.getWindow().getDecorView());
}
}
3.设置隐藏后显示导航栏
3.1.全局底部上划
——上划后底部导航栏显示4s,4s后底部导航栏隐藏
3.2.切换应用至其他APP(如APP内跳转至第三方应用、第三方APP弹窗等)
——切换至其他APP是否显示底部导航栏以第三方应用要求为准,切换至自己APP时底部导航栏消失
四、避免重复申请外设权限
当APP需要通过USB关联外设来实现业务时(比如连接USB打印机打印小票),安卓要求用户手动确认设备使用权限,来保障用户信息安全,防止木马非法入侵USB设备。
1.如何避免USB设备重新插拔同一个外设时,APP反复申请该外设权限
需要用户手动确认时,勾选“默认情况下用于该USB设备”,无法通过代码绕过该安全机制
2.如何避免设备重启后,已勾选“默认情况下用于该USB设备”的APP仍反复申请同一个外设的使用权限
2.1.在APP的AndroidManifest中指定某个Activity部分中,添加如下代码
2.2.在该目录下创建xml文档
其中,class的值需要和要连接的外设类型一致,外设class参照表如下
/**
* USB class indicating that the class is determined on a per-interface basis.
*/
public static final int USB_CLASS_PER_INTERFACE = 0;
/**
* USB class for audio devices.
*/
public static final int USB_CLASS_AUDIO = 1;
/**
* USB class for communication devices.
*/
public static final int USB_CLASS_COMM = 2;
/**
* USB class for human interface devices (for example, mice and keyboards).
*/
public static final int USB_CLASS_HID = 3;
/**
* USB class for physical devices.
*/
public static final int USB_CLASS_PHYSICA = 5;
/**
* USB class for still image devices (digital cameras).
*/
public static final int USB_CLASS_STILL_IMAGE = 6;
/**
* USB class for printers.
*/
public static final int USB_CLASS_PRINTER = 7;
/**
* USB class for mass storage devices.
*/
public static final int USB_CLASS_MASS_STORAGE = 8;
/**
* USB class for USB hubs.
*/
public static final int USB_CLASS_HUB = 9;
/**
* USB class for CDC devices (communications device class).
*/
public static final int USB_CLASS_CDC_DATA = 0x0a;
/**
* USB class for content smart card devices.
*/
public static final int USB_CLASS_CSCID = 0x0b;
/**
* USB class for content security devices.
*/
public static final int USB_CLASS_CONTENT_SEC = 0x0d;
/**
* USB class for video devices.
*/
public static final int USB_CLASS_VIDEO = 0x0e;
/**
* USB class for wireless controller devices.
*/
public static final int USB_CLASS_WIRELESS_CONTROLLER = 0xe0;
/**
* USB class for wireless miscellaneous devices.
*/
public static final int USB_CLASS_MISC = 0xef;
/**
* Application specific USB class.
*/
public static final int USB_CLASS_APP_SPEC = 0xfe;
/**
* Vendor specific USB class.
*/
public static final int USB_CLASS_VENDOR_SPEC = 0xff;
3.如何避免前两步后设置后,业务页面会因USB设备插入而刷新
安卓原生逻辑导致用户选择“默认情况下用于该USB设备”会导致USB设备插入时打开某个指定activity。如果要避免页面刷新导致业务中断,可以增加如下代码防止页面刷新。
五、如何避免自己的应用数据被清除
应用数据默认是可以通过系统设置删除的,删除后应用将恢复刚安装的状态。但是可以通过配置APP来精细管理应用数据(比如按照业务分类或时间删除数据),也可以避免重要的应用数据被删除。
在程序的manifest文件的application中加上manageSpaceActivity属性,并且指定一个Activity,这个Activity就是点击管理空间之后会跳转的那个Activity了。
PS 如果要避免数据被删除,可以创建一个自动关闭的Activity。
public class ManageSpaceActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
}// onCreate
}
七、如何避免插入usb外设导致app界面闪烁
在APP的AndroidManifest中,添加如下代码
android:configChanges="navigation|keyboardHidden|keyboard"
八、如何避免扫描枪扫出内容与实际不一致
一般情况下,文本框输入的所有内容会提交给输入法进行转换(如拼音、联想等),有的输入法经过转换后会转义部分字词导致输入内容不一致。
除了更换系统输入法为合适的输入法外,还可以利用输入法通常不对密码框进行处理的规则,调整文本框类型为“可见密码”(inputType),并且约定好可输入规范(digits)也可以避免该问题
‹EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textVisiblePassword"
android:digits="0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /›