效果图
知识储备
1、Lottie动画使用指南
2、SystemUI 中引入AAR库编译
因为在源码中加载aar或者jar包编译坑太多,我们先在 AS 中通过本地aar方式成功运行项目后,
排除各种依赖库报错问题再移植到 SystemUI 中进行编译,Android.bp 文件中引入aar、jar、so库正确编译方法(值得收藏)
以下是我整理的 lottie 依赖资源
lottie-3.4.3.aar
okio-2.1.0.jar
kotlin-stdlib-1.2.60.jar
runing.json
这里使用的是 3.4.3 版本的lottie库,低版本的库加载有的json动画文件时会报错
依赖库可以去这个网站查找并下载 MvnJar
具体实现
1、将json动画文件拷贝至assets文件夹
2、在根目录下新建libs文件夹,将aar和jar拷贝至libs中,并在libs中
新建 Android.bp 文件
android_library_import {
name: "lib-lottie",
aars: ["lottie-3.4.3.aar"],
sdk_version: "current",
}
java_import {
name: "okio-jar",
jars: ["okio-2.1.0.jar"],
sdk_version: "current",
}
java_import {
name: "okio-kotlin-jar",
jars: ["kotlin-stdlib-1.2.60.jar"],
sdk_version: "current",
}
3、在根目录下的Android.bp 中引入aar库
android_library {
name: "MtkSystemUI-core",
srcs: [
"src/**/*.kt",
"src/**/*.java",
"src/**/I*.aidl",
],
resource_dirs: [
"res-keyguard",
"res",
"res-keyguard_ext",
"res_ext",
],
static_libs: [
"okio-kotlin-jar",
"okio-jar",
"lib-lottie",
"MtkSystemUIPluginLib",
"MtkSystemUISharedLib",
"SettingsLib",
.....
4、新建 layout_lottie_charg.xml 布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottieAnimationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_autoPlay="true"/>
<TextView
android:id="@+id/tv_battery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:layout_centerHorizontal="true"
android:text="40%"
android:textSize="35dp"/>
</RelativeLayout>
5、新建 LottieActivity.java 文件
package com.android.systemui.power;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import com.airbnb.lottie.LottieAnimationView;
import com.android.systemui.R;
/**
* Created by cczheng on 2020/9/29.
*/
public class LottieActivity extends Activity {
private TextView tv_battery;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_lottie_charg);
LottieAnimationView animationView = findViewById(R.id.lottieAnimationView);
tv_battery = findViewById(R.id.tv_battery);
animationView.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
}
});
animationView.setImageAssetsFolder("assets/");
animationView.setAnimation("runing.json");
animationView.loop(true);
animationView.playAnimation();
mHandler.sendEmptyMessage(MSG_BATTERY);
registerReceiver();
}
private void registerReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(receiver, filter);
}
private void closeAnim(){
mHandler.removeMessages(MSG_BATTERY);
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_POWER_DISCONNECTED.equals(action)){
closeAnim();
}
}
};
private int MSG_BATTERY = 100;
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == MSG_BATTERY){
int batteryLevel = getBatteryLevel();
tv_battery.setText(batteryLevel +"%");
mHandler.sendEmptyMessageDelayed(MSG_BATTERY, 15000);
}
}
};
private int getBatteryLevel() {
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
}
}
优化体验
因为本文章只是提供充电动画思路,细节考虑不到位,采用Activity方式加载layout,切换时会有明显拉起动画
可以通过Window addView 方式将 layout 添加到SystemUI中,有需求的可自己去实现
判断是否是锁屏状态
KeyguardManager mKeyguardManager =
(KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
boolean lockState = mKeyguardManager.inKeyguardRestrictedInputMode();
if (lockState ) {
//锁屏
} else {
//未锁屏
}
监听充电连接与断开广播
Intent.ACTION_POWER_CONNECTED:充电连接广播
Intent.ACTION_POWER_DISCONNECTED:充电断开广播