效果图
知识储备
1、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; /** * 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:充电断开广播