AndroidQ(10.0) 手机锁屏炫酷充电动画————html方案
效果图
知识储备
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方案相关推荐
- AndroidQ(10.0) 手机锁屏炫酷充电动画————lottie方案
效果图 知识储备 1.Lottie动画使用指南 Lottie开源动画库介绍与使用示例 Android Lottie动画初探 Lottie动画免费下载网站 2.SystemUI 中引入AAR库编译 因为 ...
- android 9.0 10.0 去掉锁屏功能和息屏功能(永不息屏)
1.概述 在10.0的系统产品定制化开发中,需要对去掉锁屏功能和 息屏功能 让屏幕永远不要熄灭, 在android api中默认息屏时间为1分钟 2.去掉锁屏功能和息屏功能(永不息屏)的核心类 pac ...
- Android 10.0去除锁屏界面及SystemUI无sim卡拨打紧急电话控件显示
在开发定制化wifi版平板时,需要去掉所有紧急拨打电话的功能,而紧急拨打电话在锁屏界面 和SystemUI 的下拉快捷里面有这些功能 所以就从这两个地方入手,屏蔽到紧急拨打电话功能 1.SystemU ...
- css实现炫酷充电动画
先绘制一个电池,电池头部和电池的身体 这里其实就是两个div,使用z-index改变层级,电池的身体盖住头部,圆角使用border-radius完成 html部分,完整的css部分在最后 <di ...
- android 炫酷图案解锁,超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你...
原标题:超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你 九宫格手机解锁图案又称为手势密码,在手机屏幕上设置一笔连成的九宫格图案,在解锁时画一下设置的图案就能解锁,如今已经成为智能手机的标配,在支付 ...
- Android 炫酷的手势动画,16个超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你...
原标题:16个超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你 九宫格手机解锁图案又称为手势密码,在手机屏幕上设置一笔连成的九宫格图案,在解锁时画一下设置的图案就能解锁,如今已经成为智能手机的标配, ...
- android 魔力锁屏源码,打造最炫手机锁屏桌面 10款安卓魔力锁屏主题推荐
安卓魔力锁屏主题:个性情侣锁屏 这又是一款非常新潮的安卓魔力锁屏主题.锁屏界面上有一对情侣拿着手枪,界面展现方式与iPhone的非常相似.解锁方式采用的是屏幕下端横向拉动解锁. 安卓魔力锁屏主题:个性 ...
- 苹果手机10秒解除锁屏_Redmi 10X手机密码忘了怎么办?手机10秒解除锁屏,三步解开安卓苹果密码【详细步骤】...
智能手机在使用过程中,经常会遇到忘记密码的情况.而自己的粗心大意,导致手机无法开机,是非常烦的一件事情.今天的主角是安卓手机,针对密码忘了怎么办的问题,教大家刷机的方法,帮大家来详细解决密码忘记无法开 ...
- 苹果手机10秒解除锁屏_忘记苹果锁屏密码10秒解决 音量键选择wipedata/
导读:谈到苹果,大家应该都不陌生,有人问忘记手机密码了怎么办?,另外,还有朋友想问oppo忘记图案解锁怎么办,这到底怎么回事呢?其实锁屏密码是四位数密码呢,下面是小编精心为你们整理的忘记苹果锁屏密码1 ...
最新文章
- python抓包工具_「docker实战篇」python的docker爬虫技术-fiddler抓包软件详细配置(七)...
- HBASE_API的应用
- AWS专家论道之迁移上云的四个大趋势和七个小趋势
- python二级考试真题_全国BIM技能等级考试真题全套(一/二级,全专业,28套)
- 解决linux yum无法安装mysql
- PyInstaller打包成exe可执行文件
- 错误使用 network/train (line 340) Output data size does not match net.outputs{2}.size.
- 全新UI多用户任务悬赏系统源码+带三级分销推广
- 多卡聚合路由器在视频直播中的解决方案
- 项目管理师证怎么考?报考条件有哪些?
- hau 1031 Design T-Shirt
- iOS项目开发中的知识点与问题收集整理①
- bert实践:关系抽取解读
- 视觉技术中的图像采集卡
- iOS15.6和iOS15.5哪个更省电 iOS15.6建不建议升级
- 7种将字符串反转的 Java 方法
- 在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。
- 英雄联盟手游正式上线啦
- win7声卡驱动安装失败(不能安装)完美解决方法
- 3D目标检测论文方法汇总 【2022部分持续更新中~
热门文章
- Db2 purescale环境db2start因为缺少TSAMP license报错:SQL1677N
- Centos7安裝GitHub
- antd的联级选择器异步调用编辑回显_react-uplod-img 是一个基于 React antd组件的图片上传组件...
- php怎么读取txt文件_PHP读取文件内容的五种方式
- Gstore官网学习二:安装(笔者自带填坑)
- XDOJ32角谷定理
- 墨者学院tomcat后台弱口令漏洞利用
- 74HC165应用介绍
- 莆田学院c语言怎么查成绩,莆田学院教务管理系统成绩查询、网上选课查分登录入口...
- 使用v-cli创建项目,引入element-ui构建用户管理页面实现增删改查