效果图
知识储备
1、Lottie动画使用指南
Lottie开源动画库介绍与使用示例
Android Lottie动画初探
Lottie动画免费下载网站
2、SystemUI 中引入AAR库编译
因为在源码中加载aar或者jar包编译坑太多,我们先在 AS 中通过本地aar方式成功运行项目后,
排除各种依赖库报错问题再移植到 SystemUI 中进行编译,Android.bp 文件中引入aar、jar、so库正确编译方法(值得收藏)
以下是我整理的 lottie 依赖资源
lottie和html充电动画相关资源.zip
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
;
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:充电断开广播
参考文章
手机锁屏充电动画