充电动画
以MTK平台为例,实现充电动画
效果图
修改文件清单
- system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleBean.java
- system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleViscosity.java
- system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/WiredChargingAnimation.java
- system/vendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/wired_charging_layout.xml
- system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/power/PowerUI.java
具体实现
1、新增布局
system/vendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/.xml**
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/shcy_charge_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99000000">
<com.android.systemui.charging.BubbleViscosity
android:id="@+id/shcy_bubble_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
2、新增气泡 bean
**system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleBean.java **
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.charging;
public class BubbleBean {
private float randomY = 3;
private float x;
private float y;
private int index;
public BubbleBean(float x, float y, float randomY, int index){
this.x = x;
this.y = y;
this.randomY = randomY;
this.index = index;
}
public void set(float x, float y, float randomY, int index){
this.x = x;
this.y = y;
this.randomY = randomY;
this.index = index;
}
public void setMove(int screenHeight, int maxDistance){
if (y - maxDistance < 110){
this.y -= 2;
return;
}
if (maxDistance <= y && screenHeight -y > 110){
this.y -= randomY;
}else {
this.y -= 0.6;
}
if (index == 0){
this.x -= 0.4;
}else if (index == 2){
this.x += 0.4;
}
}
public int getIndex() {
return index;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
}
3、新增充电动画自定义 view
system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleViscosity.java
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.charging;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.jar.Attributes;
/**
* WiredCharging paint
*/
public class BubbleViscosity extends SurfaceView implements SurfaceHolder.Callback,Runnable {
private static ScheduledExecutorService scheduledThreadPool;
private Context context;
private String paintColor = "#25DA29";
private String centreColor = "#00000000";
private String minCentreColor = "#9025DA29";
private int screenHeight;
private int screenWidth;
private float lastRadius;
private float rate = 0.32f;
private float rate2 = 0.45f;
private PointF lastCurveStrat = new PointF();
private PointF lastCurveEnd = new PointF();
private PointF centreCirclePoint = new PointF();
private float centreRadius;
private float bubbleRadius;
private PointF[] arcPointStrat = new PointF[8];
private PointF[] arcPointEnd = new PointF[8];
private PointF[] control = new PointF[8];
private PointF arcStrat = new PointF();
private PointF arcEnd = new PointF();
private PointF controlP = new PointF();
List<PointF> bubbleList = new ArrayList<>();
List<BubbleBean> bubbleBeans = new ArrayList<>();
private int rotateAngle = 0;
private float controlrate = 1.66f;
private float controlrateS = 1.3f;
private int i = 0;
private SurfaceHolder mHolder;
private float scale = 0;
private Paint arcPaint;
private Paint minCentrePaint;
private Paint bubblePaint;
private Paint centrePaint;
private Paint lastPaint;
private Path lastPath;
private Random random;
private Paint textPaint;
private Paint chargerTextPaint;
private String text = "78 %";
private String chargerText = "Charging";
private Rect rect;
public BubbleViscosity(Context context) {
this(context,null);
}
public BubbleViscosity(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public BubbleViscosity(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
this.context = context;
initTool();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
screenHeight = getMeasuredHeight();
screenWidth = getMeasuredWidth();
}
private void initTool() {
rect = new Rect();
mHolder = getHolder();
mHolder.addCallback(this);
setFocusable(true);
mHolder.setFormat(PixelFormat.TRANSPARENT);
setZOrderOnTop(true);
lastRadius = dip2Dimension(40f, context);
centreRadius = dip2Dimension(100f, context);
bubbleRadius = dip2Dimension(15f, context);
random = new Random();
lastPaint = new Paint();
lastPaint.setAntiAlias(true);
lastPaint.setStyle(Paint.Style.FILL);
lastPaint.setColor(Color.parseColor(paintColor));
lastPaint.setStrokeWidth(2);
lastPath = new Path();
centrePaint = new Paint();
centrePaint.setAntiAlias(true);
centrePaint.setStyle(Paint.Style.FILL);
centrePaint.setStrokeWidth(2);
centrePaint
.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
centrePaint.setColor(Color.parseColor(centreColor));
arcPaint = new Paint();
arcPaint.setAntiAlias(true);
arcPaint.setStyle(Paint.Style.FILL);
arcPaint.setColor(Color.parseColor(paintColor));
arcPaint.setStrokeWidth(2);
minCentrePaint = new Paint();
minCentrePaint.setAntiAlias(true);
minCentrePaint.setStyle(Paint.Style.FILL);
minCentrePaint.setColor(Color.parseColor(minCentreColor));
minCentrePaint.setStrokeWidth(2);
bubblePaint = new Paint();
bubblePaint.setAntiAlias(true);
bubblePaint.setStyle(Paint.Style.FILL);
bubblePaint.setColor(Color.parseColor(minCentreColor));
bubblePaint.setStrokeWidth(2);
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setColor(Color.parseColor("#FFFFFF"));
textPaint.setStrokeWidth(2);
textPaint.setTextSize(dip2Dimension(40f, context));
chargerTextPaint = new Paint();
chargerTextPaint.setStyle(Paint.Style.FILL);
chargerTextPaint.setColor(Color.parseColor(paintColor));
chargerTextPaint.setStrokeWidth(2);
chargerTextPaint.setTextSize(dip2Dimension(20f, context));
}
public void onMDraw(){
Canvas canvas = mHolder.lockCanvas();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
bubbleDraw(canvas);
lastCircleDraw(canvas);
centreCircleDraw(canvas);
textPaint.getTextBounds(text, 0, text.length(), rect);
chargerTextPaint.getTextBounds(chargerText, 0, text.length(), rect);
canvas.drawText(text, centreCirclePoint.x - rect.width(),
centreCirclePoint.y - rect.height() / 2, textPaint);
canvas.drawText(chargerText, centreCirclePoint.x - rect.width() - rect.width() / 3,
centreCirclePoint.y + rect.height() * 2, chargerTextPaint);
mHolder.unlockCanvasAndPost(canvas);
}
public void setBatteryLevel(String level, String charger){
this.text = level+"%";
this.chargerText = charger;
postInvalidate();
}
private void centreCircleDraw(Canvas canvas){
centreCirclePoint.set(screenWidth / 2, screenHeight / 2);
circleInCoordinateDraw(canvas);
canvas.drawCircle(centreCirclePoint.x, centreCirclePoint.y, centreRadius, centrePaint);
}
private void lastCircleDraw(Canvas canvas){
lastCurveStrat.set(screenWidth / 2 - lastRadius, screenHeight);
lastCurveEnd.set((screenWidth / 2), screenHeight);
float k = (lastRadius / 2) / lastRadius;
float aX = lastRadius - lastRadius * rate2;
float aY = lastCurveStrat.y - aX * k;
float bX = lastRadius - lastRadius * rate;
float bY = lastCurveEnd.y - bX * k;
lastPath.rewind();
lastPath.moveTo(lastCurveStrat.x, lastCurveStrat.y);
lastPath.cubicTo(lastCurveStrat.x + aX, aY, lastCurveEnd.x - bX, bY, lastCurveEnd.x, lastCurveEnd.y - lastRadius / 2);
lastPath.cubicTo(lastCurveEnd.x + bX, bY, lastCurveEnd.x + lastRadius - aX, aY, lastCurveEnd.x + lastRadius, lastCurveEnd.y);
lastPath.lineTo(lastCurveStrat.x, lastCurveStrat.y);
canvas.drawPath(lastPath, lastPaint);
}
private int bubbleIndex = 0;
private void bubbleDraw(Canvas canvas){
for (int i = 0; i < bubbleBeans.size(); i++) {
if (bubbleBeans.get(i).getY() <= (int) (screenHeight / 2 + centreRadius)){
bubblePaint.setAlpha(000);
canvas.drawCircle(bubbleBeans.get(i).getX(), bubbleBeans.get(i).getY(), bubbleRadius, bubblePaint);
} else {
bubblePaint.setAlpha(150);
canvas.drawCircle(bubbleBeans.get(i).getX(), bubbleBeans.get(i).getY(), bubbleRadius, bubblePaint);
}
}
}
/**
* @param dip
* @param context
* @return
*/
public float dip2Dimension(float dip, Context context){
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
}
/**
* @param canvas
*/
public void circleInCoordinateDraw(Canvas canvas) {
int angle;
for (int i = 0; i < arcPointStrat.length; i++) {
if (i > 3 && i < 6) {
if (i == 4) {
angle = rotateAngle + i * 60;
} else {
angle = rotateAngle + i * 64;
}
} else if (i > 5) {
if (i == 6) {
angle = rotateAngle + i * 25;
} else {
angle = rotateAngle + i * 48;
}
} else {
angle = rotateAngle + i * 90;
}
float radian = (float) Math.toRadians(angle);
float adjacent = (float) Math.cos(radian) * centreRadius;
float right = (float) Math.sin(radian) * centreRadius;
float radianControl = (float) Math.toRadians(90 - (45 + angle));
float xStrat = (float) Math.cos(radianControl) * centreRadius;
float yEnd = (float) Math.sin(radianControl) * centreRadius;
if (i == 0 || i == 1) {
if (i == 1) {
arcStrat.set(centreCirclePoint.x + adjacent - scale,
centreCirclePoint.y + right + scale);
arcEnd.set(centreCirclePoint.x - right, centreCirclePoint.y
+ adjacent);
} else {
arcStrat.set(centreCirclePoint.x + adjacent,
centreCirclePoint.y + right);
arcEnd.set(centreCirclePoint.x - right - scale,
centreCirclePoint.y + adjacent + scale);
}
controlP.set(centreCirclePoint.x + yEnd * controlrate,
centreCirclePoint.y + xStrat * controlrate);
} else {
arcStrat.set(centreCirclePoint.x + adjacent,
centreCirclePoint.y + right);
arcEnd.set(centreCirclePoint.x - right, centreCirclePoint.y
+ adjacent);
if (i > 5) {
controlP.set(centreCirclePoint.x + yEnd * controlrateS,
centreCirclePoint.y + xStrat * controlrateS);
} else {
controlP.set(centreCirclePoint.x + yEnd * controlrate,
centreCirclePoint.y + xStrat * controlrate);
}
}
arcPointStrat[i] = arcStrat;
arcPointEnd[i] = arcEnd;
control[i] = controlP;
lastPath.rewind();
lastPath.moveTo(arcPointStrat[i].x, arcPointStrat[i].y);
lastPath.quadTo(control[i].x, control[i].y, arcPointEnd[i].x,
arcPointEnd[i].y);
if (i > 3 && i < 6) {
canvas.drawPath(lastPath, minCentrePaint);
} else {
canvas.drawPath(lastPath, arcPaint);
}
lastPath.rewind();
}
}
private void setAnimation() {
setScheduleWithFixedDelay(this, 0, 5);
setScheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
if (bubbleIndex > 2)
bubbleIndex = 0;
if (bubbleBeans.size() < 8) {
bubbleBeans.add(new BubbleBean(
bubbleList.get(bubbleIndex).x, bubbleList
.get(bubbleIndex).y, random.nextInt(4) + 2,
bubbleIndex));
} else {
for (int i = 0; i < bubbleBeans.size(); i++) {
if (bubbleBeans.get(i).getY() <= (int) (screenHeight / 2 + centreRadius)) {
bubbleBeans.get(i).set(
bubbleList.get(bubbleIndex).x,
bubbleList.get(bubbleIndex).y,
random.nextInt(4) + 2, bubbleIndex);
if (random.nextInt(bubbleBeans.size()) + 3 == 3 ? true
: false) {
} else {
break;
}
}
}
}
bubbleIndex++;
}
}, 0, 300);
}
private static ScheduledExecutorService getInstence() {
if (scheduledThreadPool == null) {
synchronized (BubbleViscosity.class) {
if (scheduledThreadPool == null) {
scheduledThreadPool = Executors
.newSingleThreadScheduledExecutor();
}
}
}
return scheduledThreadPool;
}
private static void setScheduleWithFixedDelay(Runnable var1, long var2,
long var4) {
getInstence().scheduleWithFixedDelay(var1, var2, var4,
TimeUnit.MILLISECONDS);
}
public static void onDestroyThread() {
getInstence().shutdownNow();
if (scheduledThreadPool != null) {
scheduledThreadPool = null;
}
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
bubbleList.clear();
setBubbleList();
startBubbleRunnable();
setAnimation();
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
onDestroyThread();
}
@Override
public void run() {
i++;
rotateAngle = i;
if (i > 90 && i < 180) {
scale += 0.25;
if (controlrateS < 1.66)
controlrateS += 0.005;
} else if (i >= 180) {
scale -= 0.12;
if (i > 300)
controlrateS -= 0.01;
}
onMDraw();
if (i == 360) {
i = 0;
rotateAngle = 0;
controlrate = 1.66f;
controlrateS = 1.3f;
scale = 0;
}
}
public void setBubbleList() {
float radian = (float) Math.toRadians(35);
float adjacent = (float) Math.cos(radian) * lastRadius / 3;
float right = (float) Math.sin(radian) * lastRadius / 3;
if (!bubbleList.isEmpty())
return;
bubbleList.add(new PointF(screenWidth / 2 - adjacent, screenHeight
- right));
bubbleList.add(new PointF(screenWidth / 2, screenHeight - lastRadius
/ 4));
bubbleList.add(new PointF(screenWidth / 2 + adjacent, screenHeight
- right));
startBubbleRunnable();
}
public void startBubbleRunnable(){
setScheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
for (int i = 0; i < bubbleBeans.size(); i++) {
bubbleBeans.get(i).setMove(screenHeight,
(int) (screenHeight / 2 + centreRadius));
}
}
}, 0, 4);
}
}
4、新增动画管理类
system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/WiredChargingAnimation.java
package com.android.systemui.charging;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.util.Slog;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import com.android.systemui.R;
import com.android.systemui.util.Utils;
public class WiredChargingAnimation {
public static final long DURATION = 5555;
private static final String TAG = "WiredChargingAnimation";
private static final boolean DEBUG = true || Log.isLoggable(TAG, Log.DEBUG);
private final WiredChargingView mCurrentWirelessChargingView;
private static WiredChargingView mPreviousWirelessChargingView;
private static boolean mShowingWiredChargingAnimation;
public StatusBarManager statusBarManager;
public static boolean isShowingWiredChargingAnimation(){
return mShowingWiredChargingAnimation;
}
public WiredChargingAnimation(@NonNull Context context, @Nullable Looper looper, int
batteryLevel, boolean isDozing) {
statusBarManager = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
mCurrentWirelessChargingView = new WiredChargingView(context, looper,
batteryLevel, isDozing);
}
public static WiredChargingAnimation makeWiredChargingAnimation(@NonNull Context context,
@Nullable Looper looper, int batteryLevel, boolean isDozing) {
mShowingWiredChargingAnimation = true;
android.util.Log.d(TAG,"makeWiredChargingAnimation batteryLevel="+batteryLevel);
return new WiredChargingAnimation(context, looper, batteryLevel, isDozing);
}
/**
* Show the view for the specified duration.
*/
public void show() {
if (mCurrentWirelessChargingView == null ||
mCurrentWirelessChargingView.mNextView == null) {
throw new RuntimeException("setView must have been called");
}
/*if (mPreviousWirelessChargingView != null) {
mPreviousWirelessChargingView.hide(0);
}*/
statusBarManager.disable(StatusBarManager.DISABLE_BACK | StatusBarManager.DISABLE_HOME | StatusBarManager.DISABLE_RECENT);
mPreviousWirelessChargingView = mCurrentWirelessChargingView;
mCurrentWirelessChargingView.show();
mCurrentWirelessChargingView.hide(DURATION);
}
public void hide(){
if (mPreviousWirelessChargingView != null) {
mPreviousWirelessChargingView.hide(0);
statusBarManager.disable(StatusBarManager.DISABLE_NONE);
}
}
private static class WiredChargingView {
private static final String CHARGE = "Charging";
private static final String FASTCHARGE = "FastCharge";
private String chargeText;
private static final int SHOW = 0;
private static final int HIDE = 1;
private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
private final Handler mHandler;
private int mGravity;
private View mView;
private View mNextView;
private WindowManager mWM;
public WiredChargingView(Context context, @Nullable Looper looper, int batteryLevel, boolean isDozing) {
//mNextView = new WirelessChargingLayout(context, batteryLevel, isDozing);
mNextView = LayoutInflater.from(context).inflate(R.layout.wired_charging_layout, null, false);
BubbleViscosity shcyBubbleViscosity = mNextView.findViewById(R.id.shcy_bubble_view);
if (Utils.isFastCharge()){
chargeText = FASTCHARGE;
}else {
chargeText = CHARGE;
}
shcyBubbleViscosity.setBatteryLevel(batteryLevel+"", chargeText);
mNextView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
hide(0);
break;
}
return false;
}
});
mGravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER;
final WindowManager.LayoutParams params = mParams;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.format = PixelFormat.TRANSLUCENT;
params.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
params.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND
| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
params.systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
params.dimAmount = 1.0f;
if (looper == null) {
// Use Looper.myLooper() if looper is not specified.
looper = Looper.myLooper();
if (looper == null) {
throw new RuntimeException(
"Can't display wireless animation on a thread that has not called "
+ "Looper.prepare()");
}
}
mHandler = new Handler(looper, null) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW: {
handleShow();
break;
}
case HIDE: {
handleHide();
// Don't do this in handleHide() because it is also invoked by
// handleShow()
mNextView = null;
mShowingWiredChargingAnimation = false;
break;
}
}
}
};
}
public void show() {
if (DEBUG) Slog.d(TAG, "SHOW: " + this);
mHandler.obtainMessage(SHOW).sendToTarget();
}
public void hide(long duration) {
mHandler.removeMessages(HIDE);
if (DEBUG) Slog.d(TAG, "HIDE: " + this);
mHandler.sendMessageDelayed(Message.obtain(mHandler, HIDE), duration);
}
private void handleShow() {
if (DEBUG) {
Slog.d(TAG, "HANDLE SHOW: " + this + " mView=" + mView + " mNextView="
+ mNextView);
}
if (mView != mNextView) {
// remove the old view if necessary
handleHide();
mView = mNextView;
Context context = mView.getContext().getApplicationContext();
String packageName = mView.getContext().getOpPackageName();
if (context == null) {
context = mView.getContext();
}
mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mParams.packageName = packageName;
mParams.hideTimeoutMilliseconds = DURATION;
if (mView.getParent() != null) {
if (DEBUG) Slog.d(TAG, "REMOVE! " + mView + " in " + this);
mWM.removeView(mView);
}
if (DEBUG) Slog.d(TAG, "ADD! " + mView + " in " + this);
try {
mWM.addView(mView, mParams);
} catch (WindowManager.BadTokenException e) {
Slog.d(TAG, "Unable to add wireless charging view. " + e);
}
}
}
private void handleHide() {
if (DEBUG) Slog.d(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
if (mView != null) {
if (mView.getParent() != null) {
if (DEBUG) Slog.d(TAG, "REMOVE! " + mView + " in " + this);
mWM.removeViewImmediate(mView);
}
mView = null;
}
}
}
}
5、动画触发(电源插入时且在锁屏下显示气泡动画)
system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/power/PowerUI.java
@SysUISingleton
public class PowerUI extends CoreStartable implements CommandQueue.Callbacks {
private final BroadcastDispatcher mBroadcastDispatcher;
private final CommandQueue mCommandQueue;
private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 start
private KeyguardManager mKeyguardManager;
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 end
@Inject
public PowerUI(Context context, BroadcastDispatcher broadcastDispatcher,
CommandQueue commandQueue, Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
WarningsUI warningsUI, EnhancedEstimates enhancedEstimates,
PowerManager powerManager) {
super(context);
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
mWarnings = warningsUI;
mEnhancedEstimates = enhancedEstimates;
mPowerManager = powerManager;
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 start
mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 end
}
.....
public void init() {
// Register for Intent broadcasts for...
IntentFilter filter = new IntentFilter();
....
filter.addAction(Intent.ACTION_USER_SWITCHED);
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 start
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 end
mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler);
....
}
....
@Override
public void onReceive(Context context, Intent intent) {
.....
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mWarnings.userSwitched();
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 start
} else if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
boolean isCharging = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.CHARGING_ANIMATE_SWITCH, 0) == 1;
android.util.Log.d("zhang", "onReceive: -> Settings -> " + isCharging);
if (mKeyguardManager.isKeyguardLocked() && isCharging){
WiredChargingAnimation.makeWiredChargingAnimation(context, null, mBatteryLevel, false).show();
}
} else if(Intent.ACTION_POWER_DISCONNECTED.equals(action)){
WiredChargingAnimation.makeWiredChargingAnimation(context, null, mBatteryLevel, false).hide();
//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 end
} else {
Slog.w(TAG, "unknown intent: " + intent);
}
}
......
}