手机锁屏充电动画

手机锁屏时充电动画

需求:插入手机充电线后,手机锁屏状态时,亮屏并显示充电动画效果
设计思想:
SystemUI监听充电线的插入和拔出
插入充电线时,启动一个Service,加载充电动画,动画布局中的电量使用TextView显示,动画使用lottie播放

关键步骤与技术点

充电连接与断开广播
Intent.ACTION_POWER_CONNECTED:充电连接广播
Intent.ACTION_POWER_DISCONNECTED:充电断开广播
是否是锁屏状态:

KeyguardManager mKeyguardManager =
 (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
boolean lockState = mKeyguardManager.inKeyguardRestrictedInputMode();
if (lockState ) {
    //锁屏
} else {
    //未锁屏
}

充电动画时json文件,不是帧动画的图片,所以采用lottie开源库播放动画
Android Studio导入lottie库的方式网上有很多,但是源码的方式没有。
本次使用的lottie版本是2.7.0,再往上的版本就要使用androidx的库了。
本文描述SystemUI导入lottie方法

SystemUI导入lottie方法

下载lottie-2.7.0.aar

使用Android Studio的方式导入lottie库,把lottie-2.7.0.aar下载到本地,放入项目的libs目录下

Android.mk修改

#预编译lottie库
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := lottie-2.7.0:libs/lottie-2.7.0.aar
#其它库的的预编译
include $(BUILD_MULTI_PREBUILT)

#导入lottie库
LOCAL_STATIC_JAVA_AAR_LIBRARIES := lottie-2.7.0

#合并打包库的资源文件时需要,并且记住是一个包名对应一个–extra-packges
LOCAL_AAPT_FLAGS += --auto-add-overlay --extra-packages com.airbnb.lottie
–extra-packages xxxxxxxxx #其它需要aapt的库的包名

#把aar中的资源文件解压出来放入res-lottie目录进行资源编译,否则编译时会提示找不到资源,运行时会报错
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res-lottie

在AndroidManifest中增加如下的代码,否则会报aar中的manifest与主manifest中的minSdk不一样的错误。没有的话,有的环境能够编译通过,有的编译不通过

充电动画布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/float_id"
    style="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0000">

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/lottie_likeanim"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />

    <ImageView
        android:id="@+id/charge_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="854px"
        android:layout_marginBottom="659px"
        android:src="@drawable/icon_notify_battery_charging"
        tools:background="#000" />

    <TextView
        android:id="@+id/percent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="13px"
        android:layout_marginBottom="621px"
        android:layout_toEndOf="@id/charge_mode"
        android:fontFamily="sans-serif"
        android:textColor="#FFF"
        android:textSize="100px" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="8px"
        android:layout_marginBottom="621px"
        android:layout_toEndOf="@+id/percent"
        android:fontFamily="sans-serif"
        android:text="%"
        android:textColor="#FFF"
        android:textSize="70px" />
</RelativeLayout>

上述xml布局是主体布局,通过WindowManger添加的窗口显示。再Window上加载xml的关键代码如下

        wmParams = new LayoutParams();
        mWindowManager = (WindowManager) getApplication().getSystemService(WINDOW_SERVICE);
        wmParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        wmParams.type = LayoutParams.TYPE_NAVIGATION_BAR_PANEL; //显示在锁屏之上,并且能够接收事件
        wmParams.format = PixelFormat.RGBA_8888;
        wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                LayoutParams.FLAG_LAYOUT_NO_LIMITS | LayoutParams.FLAG_FULLSCREEN;
        wmParams.gravity = Gravity.START | Gravity.TOP;

        int statusBarHeight = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
        wmParams.x = 0;
        wmParams.y = -statusBarHeight;
        wmParams.width = 1080;
        wmParams.height = 1920;
        mRootView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.anim, null, false);
        mWindowManager.addView(mRootView, wmParams);

使用lottie播放json动画

通过LottieAnimationView控件播放json动画,关键代码如下

lavChargingAnimView = mRootView.findViewById(R.id.lottie_likeanim);
if (lavChargingAnimView != null) {
    animData = "animdata_high.json"
    lavChargingAnimView.setAnimation(animData);
    lavChargingAnimView.loop(true);
    lavChargingAnimView.playAnimation();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值