摘要
在使用 CocosCreator 打包的原生应用中,我们可以通过引擎封装好的反射机制调用 Java 的静态方法,从而实现提示、相册、支付跳转等功能。本次内容为利用 jsb 读取返回的电池信息。
正文
先看效果
版本说明
- CocosCreator 为 2.2.1 版本。
- AndroidStudio 为 3.5.2 版本。
- JDK 为 13 版本。(具体:13.0.1)
- NDK 为 20 版本。(具体:20.1.5948944)
- SDK 安装了 API 23 的。
- 模拟器为 AVD。(可以在 AndroidStudio 内安装)
布局与脚本
在 CocosCreator 中布局好文本和电池图片,如图。(电池由一个背景和十个矩形图片组合而成)
电池信息的显示
通过布局组件,让十个表示电量的电池块均匀摆放,然后写一个通过个数控制的方法。
/**
* 10个格子,显示几个
* @param fillIndex
*/
updateBatteryShowStateByCount (showCount: number) {
const array = this.powers.children
array.forEach((ele, index) => {
if (index < showCount) {
ele.opacity = 255
} else {
ele.opacity = 0
}
})
}
这样我们就能根据传入的 0 - 10 来控制显示。但是,电量应该是 0 - 100 的,我们应该再封装一层。
// this.powerCount 表示电量 0 - 100
// this.v 表示电池电压,单位是 mV
// this.batteryState 表示电池状态,充电还是放电
// 根据数据调整电量格子显示
updateBatteryShowState () {
const n = Math.floor(this.powerCount / 10)
this.updateBatteryShowStateByCount(n)
}
// 根据数据显示于 Label 组件
updateInfoShow () {
const labs = this.infoMgr.getComponentsInChildren(cc.Label)
labs[0].string = `${this.powerCount}%`
labs[1].string = this.batteryState
labs[2].string = this.v + "毫伏(mV)"
}
约定信息格式
显示我们都做好了,然后我们获取电池信息后怎么传回来呢?cocos 反射方法有整数、小数、字符串和空值这几个类型,那么我们可以选择小数、整数和字符串。为了方便,我决定将小数、整数都拼接成字符串传过来,到了 cocos 再解析一下。
// 约定格式 xx,xx,xx,xx 然后用 split(",") 进行切割
getElect () {
const className = "org/cocos2dx/javascript/AppActivity"
const info = jsb.reflection.callStaticMethod(className, "getElect", "()Ljava/lang/String;")
if (!info) {
cc.log("jsb get null")
return
}
const array = info.split(",")
const level = parseInt(array[0])
const scale = parseInt(array[1])
const status = array[2]
const voltage = parseInt(array[3])
this.powerCount = (level * 100) / scale
this.batteryState = status
this.v = voltage
// 数据赋值完毕后刷新电池格数与 Label 显示
this.updateAll()
}
那么我们多长时间取一次信息呢?因为电池信息的获取不需要那么频繁,1秒左右都可以,我这里定为 2 秒。
update (dt: number) {
this.timeTemp += dt
if (this.timeTemp > 2) {
this.timeTemp = 0
this.getElect()
}
}
Java获取信息
在 Android Studio 中如何获取电池电量呢?贼简单!
public static String getElect() {
// 参数:电池信息改变时
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent receiver = app.registerReceiver(null, filter);
// 利用 getIntExtra 获取信息
int level = receiver.getIntExtra("level", 0); //获取当前电量
int scale = receiver.getIntExtra("scale", 0); //获取总电量
int status = receiver.getIntExtra("status", 0); //获取充电状态
int voltage = receiver.getIntExtra("voltage", 0);//获取电压(mv)
// 电池状态
String batteryStatus = "";
switch (status) {
case BatteryManager.BATTERY_STATUS_UNKNOWN:
batteryStatus = "[没有安装电池]";
break;
case BatteryManager.BATTERY_STATUS_CHARGING:
batteryStatus = "[正在充电]";
break;
case BatteryManager.BATTERY_STATUS_FULL:
batteryStatus = "[已经充满]";
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
batteryStatus = "[放电中]";
break;
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
batteryStatus = "[未充电]";
break;
default:
batteryStatus = "[未知状态]";
break;
}
// 将信息拼接成 xx,xx,xx,xx 的形式
StringBuilder info = new StringBuilder();
info.append(level);
info.append(",");
info.append(scale);
info.append(",");
info.append(batteryStatus);
info.append(",");
info.append(voltage);
return info.toString();
}
对了,app 这个变量是这么来的:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isTaskRoot()) {
return;
}
SDKWrapper.getInstance().init(this);
// 这里,记得先声明 private static AppActivity app = null;
app = this;
}
真机测试
结语
有意思吧!学会了没?
O(∩_∩)O~~