效果图

知识储备

1、WebView加载html,并通过JS传值

在网上随便搜索找到了这个炫酷的充电动画,可惜是css实现的,想在Android中使用那只能

通过 WebView 来加载了,要传递当前系统电量需要在Java和JS中传值,具体可参考下面的文章

Android如何使用HTML做界面——WebView控件

Android:你要的WebView与 JS 交互方式 都在这里了

2、SystemUI 中使用 WebView 控件排错

开始在普通工程中使用WebView是没有问题的,但移植到SystemUI中运行的时候出现错误

AndroidRuntime: Caused by: java.lang.UnsupportedOperationException: For security reasons, WebView is not

allowed in privileged processes

解决办法,添加 hookWebView() 方法 解决 WebView 报错 Binary XML file line #7 Error inflating class android.webkit.WebView

具体实现

1、将html文件拷贝至assets文件夹

lottie和html充电动画相关资源.zip

2、新建 layout_charge.xml 布局文件


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/transparent"><WebViewandroid:id="@+id/webView"android:layout_width="match_parent"android:layout_height="match_parent"></WebView><FrameLayoutandroid:id="@+id/clickView"android:layout_width="match_parent"android:layout_height="match_parent"/>
</FrameLayout>

3、新建 ChargeActivity.java 文件


package com.android.systemui.power;
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.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import com.android.systemui.R;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class ChargeActivity extends Activity {private WebView mWebView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);hookWebView();setContentView(R.layout.layout_charge);mWebView = (WebView) findViewById(R.id.webView);FrameLayout mClickView = (FrameLayout) findViewById(R.id.clickView);mWebView.setVisibility(View.INVISIBLE);WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);webSettings.setDomStorageEnabled(true);mWebView.loadUrl("file:///android_asset/charging.html");mWebView.setWebViewClient(new WebViewClient(){@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);mWebView.setVisibility(View.VISIBLE);mHandler.sendEmptyMessage(MSG_BATTERY);}});mClickView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {closeAnim();}});registerReceiver();}public static void hookWebView(){int sdkInt = Build.VERSION.SDK_INT;try {Class<?> factoryClass = Class.forName("android.webkit.WebViewFactory");Field field = factoryClass.getDeclaredField("sProviderInstance");field.setAccessible(true);Object sProviderInstance = field.get(null);if (sProviderInstance != null) {Log.i("hook","sProviderInstance isn't null");return;}Method getProviderClassMethod;if (sdkInt > 22) {getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");} else if (sdkInt == 22) {getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");} else {Log.i("hook","Don't need to Hook WebView");return;}getProviderClassMethod.setAccessible(true);Class<?> factoryProviderClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");Constructor<?> delegateConstructor = delegateClass.getDeclaredConstructor();delegateConstructor.setAccessible(true);if(sdkInt < 26){Constructor<?> providerConstructor = factoryProviderClass.getConstructor(delegateClass);if (providerConstructor != null) {providerConstructor.setAccessible(true);sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance());}} else {Field chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD");chromiumMethodName.setAccessible(true);String chromiumMethodNameStr = (String)chromiumMethodName.get(null);if (chromiumMethodNameStr == null) {chromiumMethodNameStr = "create";}Method staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass);if (staticFactory!=null){sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance());}}if (sProviderInstance != null){field.set("sProviderInstance", sProviderInstance);Log.i("hook","Hook success!");} else {Log.i("hook","Hook failed!");}} catch (Throwable e) {Log.w("hook",e);e.printStackTrace();}}private void closeAnim(){mHandler.removeMessages(MSG_BATTERY);finish();}private void registerReceiver() {IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_POWER_DISCONNECTED);registerReceiver(receiver, filter);}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(receiver);}private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic 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(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == MSG_BATTERY){changeBatteryText();mHandler.sendEmptyMessageDelayed(MSG_BATTERY, 15000);}}};private int getBatteryLevel() {BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);}private void changeBatteryText() {mWebView.post(new Runnable() {@Overridepublic void run() {String mbettery = getBatteryLevel() + "%";Log.e("ccz", "mbettery=" + mbettery);mWebView.evaluateJavascript("javascript:callJSWithArgs('" + mbettery + "')", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {//Toast.makeText(getApplication(), " "+value, Toast.LENGTH_SHORT).show();}});}});}
}

优化体验

因为本文章只是提供充电动画思路,细节考虑不到位,采用Activity方式加载layout,

切换时会有明显拉起动画,可以通过Window addView 方式将 layout 添加到SystemUI中,

有需求的可自己去实现

参考文章

android 高仿华为充电动画

css3安卓充电动画效果

AndroidQ(10.0) 手机锁屏炫酷充电动画————html方案相关推荐

  1. AndroidQ(10.0) 手机锁屏炫酷充电动画————lottie方案

    效果图 知识储备 1.Lottie动画使用指南 Lottie开源动画库介绍与使用示例 Android Lottie动画初探 Lottie动画免费下载网站 2.SystemUI 中引入AAR库编译 因为 ...

  2. android 9.0 10.0 去掉锁屏功能和息屏功能(永不息屏)

    1.概述 在10.0的系统产品定制化开发中,需要对去掉锁屏功能和 息屏功能 让屏幕永远不要熄灭, 在android api中默认息屏时间为1分钟 2.去掉锁屏功能和息屏功能(永不息屏)的核心类 pac ...

  3. Android 10.0去除锁屏界面及SystemUI无sim卡拨打紧急电话控件显示

    在开发定制化wifi版平板时,需要去掉所有紧急拨打电话的功能,而紧急拨打电话在锁屏界面 和SystemUI 的下拉快捷里面有这些功能 所以就从这两个地方入手,屏蔽到紧急拨打电话功能 1.SystemU ...

  4. css实现炫酷充电动画

    先绘制一个电池,电池头部和电池的身体 这里其实就是两个div,使用z-index改变层级,电池的身体盖住头部,圆角使用border-radius完成 html部分,完整的css部分在最后 <di ...

  5. android 炫酷图案解锁,超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你...

    原标题:超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你 九宫格手机解锁图案又称为手势密码,在手机屏幕上设置一笔连成的九宫格图案,在解锁时画一下设置的图案就能解锁,如今已经成为智能手机的标配,在支付 ...

  6. Android 炫酷的手势动画,16个超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你...

    原标题:16个超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你 九宫格手机解锁图案又称为手势密码,在手机屏幕上设置一笔连成的九宫格图案,在解锁时画一下设置的图案就能解锁,如今已经成为智能手机的标配, ...

  7. android 魔力锁屏源码,打造最炫手机锁屏桌面 10款安卓魔力锁屏主题推荐

    安卓魔力锁屏主题:个性情侣锁屏 这又是一款非常新潮的安卓魔力锁屏主题.锁屏界面上有一对情侣拿着手枪,界面展现方式与iPhone的非常相似.解锁方式采用的是屏幕下端横向拉动解锁. 安卓魔力锁屏主题:个性 ...

  8. 苹果手机10秒解除锁屏_Redmi 10X手机密码忘了怎么办?手机10秒解除锁屏,三步解开安卓苹果密码【详细步骤】...

    智能手机在使用过程中,经常会遇到忘记密码的情况.而自己的粗心大意,导致手机无法开机,是非常烦的一件事情.今天的主角是安卓手机,针对密码忘了怎么办的问题,教大家刷机的方法,帮大家来详细解决密码忘记无法开 ...

  9. 苹果手机10秒解除锁屏_忘记苹果锁屏密码10秒解决 音量键选择wipedata/

    导读:谈到苹果,大家应该都不陌生,有人问忘记手机密码了怎么办?,另外,还有朋友想问oppo忘记图案解锁怎么办,这到底怎么回事呢?其实锁屏密码是四位数密码呢,下面是小编精心为你们整理的忘记苹果锁屏密码1 ...

最新文章

  1. python抓包工具_「docker实战篇」python的docker爬虫技术-fiddler抓包软件详细配置(七)...
  2. HBASE_API的应用
  3. AWS专家论道之迁移上云的四个大趋势和七个小趋势
  4. python二级考试真题_全国BIM技能等级考试真题全套(一/二级,全专业,28套)
  5. 解决linux yum无法安装mysql
  6. PyInstaller打包成exe可执行文件
  7. 错误使用 network/train (line 340) Output data size does not match net.outputs{2}.size.
  8. 全新UI多用户任务悬赏系统源码+带三级分销推广
  9. 多卡聚合路由器在视频直播中的解决方案
  10. 项目管理师证怎么考?报考条件有哪些?
  11. hau 1031 Design T-Shirt
  12. iOS项目开发中的知识点与问题收集整理①
  13. bert实践:关系抽取解读
  14. 视觉技术中的图像采集卡
  15. iOS15.6和iOS15.5哪个更省电 iOS15.6建不建议升级
  16. 7种将字符串反转的 Java 方法
  17. 在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。
  18. 英雄联盟手游正式上线啦
  19. win7声卡驱动安装失败(不能安装)完美解决方法
  20. 3D目标检测论文方法汇总 【2022部分持续更新中~

热门文章

  1. Db2 purescale环境db2start因为缺少TSAMP license报错:SQL1677N
  2. Centos7安裝GitHub
  3. antd的联级选择器异步调用编辑回显_react-uplod-img 是一个基于 React antd组件的图片上传组件...
  4. php怎么读取txt文件_PHP读取文件内容的五种方式
  5. Gstore官网学习二:安装(笔者自带填坑)
  6. XDOJ32角谷定理
  7. 墨者学院tomcat后台弱口令漏洞利用
  8. 74HC165应用介绍
  9. 莆田学院c语言怎么查成绩,莆田学院教务管理系统成绩查询、网上选课查分登录入口...
  10. 使用v-cli创建项目,引入element-ui构建用户管理页面实现增删改查