Andrioid T 实现充电动画(2)

news/2024/5/17 18:41:04 标签: gitee

Andrioid T 实现充电动画(2)

以MTK平台为例,实现充电动画

效果图在这里插入图片描述

资源包

修改文件清单

  1. system/vendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/prize_charge_layout.xml
  2. system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/KeyguardChargeAnimationView.java
  3. system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/WiredChargingAnimation02.java
  4. system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/power/PowerUI.java
  5. system/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/util/Utils.java

具体实现

1、新增布局

prize_charge_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.charging.KeyguardChargeAnimationView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
    xmlns:sysui="http://schemas.android.com/apk/res-auto"
    android:id="@+id/keyguard_charge_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#e6000000">

    <ImageView
        android:id="@+id/dot_view"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:padding="0dp"
        android:src="@drawable/prize_charge_dot" />

    <ImageView
        android:id="@+id/ring_view"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:padding="0dp"
        android:src="@drawable/prize_charge_ring" />

    <RelativeLayout
        android:id="@+id/battery_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal">

        <LinearLayout
            android:id="@+id/charge_battery"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/charge_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="1dp"
                android:layout_marginRight="3dp" />

            <TextView
                android:id="@+id/battery_level"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:fontFamily="sans-serif-light"
                android:textColor="#ffffff"
                android:textSize="28dp" />
        </LinearLayout>

        <TextView
            android:id="@+id/battery_prompt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/charge_battery"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="20dp"
            android:fontFamily="sans-serif-light"
            android:textColor="#ffffff"
            android:textSize="14dp" />
    </RelativeLayout>
</com.android.systemui.charging.KeyguardChargeAnimationView>
2、布局对应的animate java类

KeyguardChargeAnimationView.java

package com.android.systemui.charging;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.android.systemui.R;
import com.android.systemui.util.Utils;

import java.util.ArrayList;
import java.util.List;

public class KeyguardChargeAnimationView extends RelativeLayout {

	private final int BORN_STAR_WIDTH = 300;
	private final int CREATE_STAR_MSG = 10002;
	private final int STARS_INTERVAL = 350;
	private int battery;
	private TextView batteryLevelTxt;
	private TextView batteryPromptTxt;
	private Bitmap batterySourceBmp;
	private Bitmap[] batteryStar;
	private final int chargeColor = -1;
	private ImageView chargeIcon;
	private ImageView dotView;
	private final int fastChargeColor = -12910685;
	private int height;
	private boolean isPause = false;
	private boolean isScreenOn = true;

	Handler mHandler = new Handler() {
		public void handleMessage(Message message) {
			super.handleMessage(message);
			if (message.what == 10002) {
				createOneStar();
			}
		}
	};
	private AnimationListener onAnimationListener;
	private Paint paint;
	private ImageView ringView;
	private int speedUpFactor = 3;
	private List<Star> starList;
	private long updateTime = 0;
	private int width;

	public abstract class AnimationListener {
		public abstract void onAnimationEnd();

		public abstract void onAnimationStart();
	}


	private Runnable hideKeyguardChargeAnimationView = new Runnable() {
		@Override
		public void run() {
			anim2hide();
		}
	};

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			return true;
		}
		if (ev.getAction() == MotionEvent.ACTION_UP) {
			anim2hide();
			return true;
		}
		return super.dispatchTouchEvent(ev);
	}

	public void closeByDelay() {
		removeCallbacks(hideKeyguardChargeAnimationView);
		postDelayed(hideKeyguardChargeAnimationView, 5 * 1000);
	}

	public class Star {
		public Bitmap bitmap;
		public float horSpeed;
		public boolean isLeft;
		public float offx;
		public int swingDistance;
		public float verSpeed;
		public int x;
		public int y;

		public Star() {
		}
	}


	public void anim2Show(boolean screen_on) {
		if (battery < 100) {
			start();
		} else {
			stop();
		}

		if (!screen_on) {
			this.setAlpha(1.0f);
			setVisibility(VISIBLE);
			return;
		}

		if (getVisibility() == VISIBLE) {
			return;
		}

		this.setAlpha(0);
		this.setVisibility(VISIBLE);

		chargeViewHideAnimator = ValueAnimator.ofFloat(new float[]{0.0f, 1.0f});
		chargeViewHideAnimator.setDuration(500);
		chargeViewHideAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			public void onAnimationUpdate(ValueAnimator valueAnimator) {
				setAlpha(((Float) valueAnimator.getAnimatedValue()).floatValue());
			}
		});
		chargeViewHideAnimator.addListener(new AnimatorListenerAdapter() {
			public void onAnimationEnd(Animator animator) {
				super.onAnimationEnd(animator);
				chargeViewHideAnimator = null;
				setAlpha(1.0f);
				setVisibility(VISIBLE);
			}
		});
		chargeViewHideAnimator.start();

	}

	private ValueAnimator chargeViewHideAnimator;

	public void anim2hide() {
		removeCallbacks(hideKeyguardChargeAnimationView);
		if (getVisibility() != VISIBLE) {
			return;
		}
		chargeViewHideAnimator = ValueAnimator.ofFloat(new float[]{1.0f, 0.0f});
		chargeViewHideAnimator.setDuration(500);
		chargeViewHideAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			public void onAnimationUpdate(ValueAnimator valueAnimator) {
				setAlpha(((Float) valueAnimator.getAnimatedValue()).floatValue());
			}
		});
		chargeViewHideAnimator.addListener(new AnimatorListenerAdapter() {
			public void onAnimationEnd(Animator animator) {
				super.onAnimationEnd(animator);
				chargeViewHideAnimator = null;
				setAlpha(0.0f);
				setVisibility(INVISIBLE);
				stop();
			}
		});
		chargeViewHideAnimator.start();
	}

	public KeyguardChargeAnimationView(Context context) {
		super(context);
		init();
	}

	public KeyguardChargeAnimationView(Context context, AttributeSet attributeSet) {
		super(context, attributeSet);
		init();
	}

	public KeyguardChargeAnimationView(Context context, AttributeSet attributeSet, int i) {
		super(context, attributeSet, i);
		init();
	}

	public KeyguardChargeAnimationView(Context context, AttributeSet attributeSet, int i, int i2) {
		super(context, attributeSet, i, i2);
		init();
	}

	private void init() {
		this.starList = new ArrayList();
		this.paint = new Paint(1);
		this.paint.setAntiAlias(true);
		this.paint.setFilterBitmap(true);
		this.paint.setDither(true);
		this.batterySourceBmp = BitmapFactory.decodeResource(getResources(), R.drawable.prize_charge_batterysource);
		this.batteryStar = new Bitmap[]{BitmapFactory.decodeResource(getResources(), R.drawable.prize_charge_star_s),
				BitmapFactory.decodeResource(getResources(), R.drawable.prize_charge_star_m),
				BitmapFactory.decodeResource(getResources(), R.drawable.prize_charge_star_b)};
	}

	/* access modifiers changed from: protected */
	public void onFinishInflate() {
		super.onFinishInflate();
		this.ringView = (ImageView) findViewById(R.id.ring_view);
		this.dotView = (ImageView) findViewById(R.id.dot_view);
		startViewRingAnimation(this.ringView, 30000);
		startViewRingAnimation(this.dotView, 60000);
		this.chargeIcon = (ImageView) findViewById(R.id.charge_icon);
		this.batteryLevelTxt = (TextView) findViewById(R.id.battery_level);
		this.batteryPromptTxt = (TextView) findViewById(R.id.battery_prompt);
	}

	private void startViewRingAnimation(ImageView imageView, long j) {
		if (imageView != null) {
			RotateAnimation rotateAnimation = new RotateAnimation(0.0f, 360.0f, 1, 0.5f, 1, 0.5f);
			rotateAnimation.setInterpolator(new LinearInterpolator());
			rotateAnimation.setDuration(j);
			rotateAnimation.setRepeatCount(-1);
			rotateAnimation.setFillAfter(true);
			imageView.startAnimation(rotateAnimation);
		}
	}

	public void updateChargeIcon() {
		ImageView imageView = this.chargeIcon;
		if (imageView != null) {
			if (Utils.isFastCharge()) {
				imageView.setImageResource(R.drawable.prize_charge_fast_icon);
				this.chargeIcon.setColorFilter(-12910685);
			} else {
				imageView.setImageResource(R.drawable.prize_charge_icon);
				this.chargeIcon.setColorFilter(-1);
			}
		}
	}

	public void updateBatteryLevel() {
		TextView textView = this.batteryLevelTxt;
		if (textView != null) {
			StringBuilder sb = new StringBuilder();
			sb.append(this.battery);
			sb.append("%");
			textView.setText(sb.toString());
			if (Utils.isFastCharge()) {
				this.batteryLevelTxt.setTextColor(-12910685);
				this.batteryPromptTxt.setText(getContext().getString(R.string.charge_fast_pk));
			} else {
				this.batteryLevelTxt.setTextColor(-1);
				this.batteryPromptTxt.setText(getContext().getString(R.string.charge_slow));
			}
		}
	}


	public void start() {
		if ((this.isPause || this.speedUpFactor != 1) && this.isScreenOn) {
			this.isPause = false;
			this.speedUpFactor = 1;
			this.mHandler.removeMessages(10002);
			createOneStar();
			AnimationListener animationListener = this.onAnimationListener;
			if (animationListener != null) {
				animationListener.onAnimationStart();
			}
		}
	}

	public void stop() {
		this.isPause = true;
		this.speedUpFactor = 3;
		this.mHandler.removeMessages(10002);
		synchronized (this.starList) {
			this.starList.clear();
		}
	}

	/* access modifiers changed from: private */
	public void createOneStar() {
		synchronized (this.starList) {
			Star star = new Star();
			star.bitmap = this.batteryStar[(int) (Math.random() * ((double) this.batteryStar.length))];
			star.x = (int) (((double) ((this.width - 300) / 2)) + (Math.random() * ((double) (300 - star.bitmap.getWidth()))));
			star.y = this.height;
			star.verSpeed = (float) (Utils.isFastCharge() ? 4.5d : 2.5d + (Math.random() * 2.0d));
			star.horSpeed = (float) (Math.random() + 0.5d);
			star.isLeft = Math.random() <= 0.5d;
			double d = (double) 100;
			star.swingDistance = (int) (d + (Math.random() * d));
			if (getVisibility() == 0) {
				this.starList.add(star);
			}
			if (!this.isPause) {
				this.mHandler.removeMessages(10002);
				this.mHandler.sendEmptyMessageDelayed(10002, 350);
				if (this.starList.size() == 1) {
					invalidate();
				}
			}
		}
	}

	/* access modifiers changed from: protected */
	public void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if (this.width == 0 || this.height == 0) {
			Display defaultDisplay = ((WindowManager) getContext().getSystemService("window")).getDefaultDisplay();
			DisplayMetrics displayMetrics = new DisplayMetrics();
			defaultDisplay.getRealMetrics(displayMetrics);
			this.width = displayMetrics.widthPixels;
			this.height = displayMetrics.heightPixels;
		}
		int i = this.width;
		int i2 = this.height;
		if (i > i2) {
			this.width = i2;
			this.height = i;
		}
		if (this.width != 0 && this.height != 0) {
			synchronized (this.starList) {
				drawBatterySourceBmp(canvas);
				drawStars(canvas);
				updateChargeIcon();
				updateBatteryLevel();
				invalidate();
			}
		}
	}

	private void drawStars(Canvas canvas) {
		if (this.battery != 100) {
			List<Star> list = this.starList;
			if (!(list == null || list.size() == 0)) {
				if (this.updateTime == 0) {
					this.updateTime = System.currentTimeMillis();
				}
				long currentTimeMillis = System.currentTimeMillis();
				int i = 0;
				boolean z = currentTimeMillis - this.updateTime >= 15;
				while (i < this.starList.size()) {
					Star star = (Star) this.starList.get(i);
					Bitmap bitmap = star.bitmap;
					if (bitmap != null && !bitmap.isRecycled()) {
						canvas.drawBitmap(star.bitmap, ((float) star.x) + star.offx, (float) star.y, this.paint);
						if (z) {
							this.updateTime = currentTimeMillis;
							if (updateStar(star)) {
								this.starList.remove(star);
								if (this.starList.size() == 0) {
									AnimationListener animationListener = this.onAnimationListener;
									if (animationListener != null) {
										animationListener.onAnimationEnd();
									}
								}
								i--;
							}
						}
					}
					i++;
				}
			}
		}
	}

	private boolean updateStar(Star star) {
		if (star.isLeft) {
			star.offx -= star.horSpeed * ((float) this.speedUpFactor);
			if (star.offx <= ((float) (-star.swingDistance))) {
				star.isLeft = false;
			}
			if (((float) star.x) + star.offx <= ((float) ((this.width - 300) / 2))) {
				star.isLeft = false;
			}
		} else {
			star.offx += star.horSpeed * ((float) this.speedUpFactor);
			if (star.offx >= ((float) star.swingDistance)) {
				star.isLeft = true;
			}
			if (((float) star.x) + star.offx >= ((float) (((this.width + 300) / 2) - star.bitmap.getWidth()))) {
				star.isLeft = true;
			}
		}
		star.y = (int) (((float) star.y) - (star.verSpeed * ((float) this.speedUpFactor)));
		ImageView imageView = this.ringView;
		return star.y <= (imageView != null ? imageView.getBottom() - ((int) (((float) this.ringView.getHeight()) * 0.1f)) : 0);
	}

	private void drawBatterySourceBmp(Canvas canvas) {
		if (this.battery != 100) {
			Bitmap bitmap = this.batterySourceBmp;
			if (bitmap != null && !bitmap.isRecycled()) {
				canvas.drawBitmap(this.batterySourceBmp, (float) ((this.width - this.batterySourceBmp.getWidth()) / 2),
						(float) (this.height - this.batterySourceBmp.getHeight()), this.paint);
			}
		}
	}

	/* access modifiers changed from: protected */
	public void onDetachedFromWindow() {
		super.onDetachedFromWindow();
	}

	public void setBattery(int i) {
		this.battery = i;
	}
}
3、新增动画管理类

WiredChargingAnimation02

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.tinno.feature.TinnoFeature;

public class WiredChargingAnimation02 {
	public static final long DURATION = 5555;
	private static final String TAG = "WiredChargingAnimation02";
	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 WiredChargingAnimation02 (@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 WiredChargingAnimation02 makeWiredChargingAnimation(@NonNull Context context,
																	@Nullable Looper looper, int batteryLevel, boolean isDozing) {
		mShowingWiredChargingAnimation = true;
		return new WiredChargingAnimation02(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 String CHARGE = "";
		private static String FASTCHARGE = "";
		private String chargeText;

		private static final int SHOW = 0;
		private static final int HIDE = 1;

		private final Handler mHandler;


		private WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();

		private View mView;

		private View mNextView;

		private WindowManager mWM;

		KeyguardChargeAnimationView chargeView;

		private static final int MSG_SHOW = 0x88;
		boolean isShowChargingView;

		private Handler handler = new Handler(Looper.myLooper()){
			@Override
			public void handleMessage(@NonNull Message msg) {
				super.handleMessage(msg);
				switch (msg.what){
					case MSG_SHOW:
						showContext();
						sendEmptyMessageDelayed(MSG_SHOW, 500);
						break;
				}
			}
		};

		public WiredChargingView(Context context, @Nullable Looper looper, int batteryLevel, boolean isDozing) {

			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;
			mNextView = LayoutInflater.from(context).inflate(R.layout.prize_charge_layout, null, false);
			isShowChargingView = true;

			chargeView = (KeyguardChargeAnimationView)mNextView.findViewById(R.id.keyguard_charge_view);
			chargeView.setBattery(batteryLevel);
			showContext();
			handler.sendEmptyMessageDelayed(MSG_SHOW, 500);
			mNextView.setOnTouchListener(new View.OnTouchListener() {
  				@Override
  				public boolean onTouch(View v, MotionEvent event) {
				  	if (event.getAction() == MotionEvent.ACTION_DOWN) {
						  return true;
				  	}
				  	if (event.getAction() == MotionEvent.ACTION_UP) {
						  handleHide();
						  return true;
				  	}
					  return true;
			  	}
			});

			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()
							handler.removeMessages(MSG_SHOW);
							mNextView = null;
							mShowingWiredChargingAnimation = false;
							break;
						}
					}
				}
			};
		}

		public void showContext(){
			chargeView.updateChargeIcon();
			chargeView.updateBatteryLevel();
		}

		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;
				chargeView.anim2Show(true);
				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);
					chargeView.anim2hide();
					mWM.removeViewImmediate(mView);
				}

				mView = null;
			}
		}
	}
}
4、动画触发(电源插入时且在锁屏下显示气泡动画)
@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){
                    WiredChargingAnimation02.makeWiredChargingAnimation(context,null,mBatteryLevel,false).show();
                }
            } else if(Intent.ACTION_POWER_DISCONNECTED.equals(action)){
               	WiredChargingAnimation02.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);
            }
   }

   ......
       
}

5、读取充电电压,判断是否达到6V快充条件
/*
 * Copyright (C) 2017 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.util;

import static android.view.Display.DEFAULT_DISPLAY;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.provider.Settings;
import android.view.DisplayCutout;

import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.R;
import com.android.systemui.shared.system.QuickStepContract;

//TN modify for bug VFFASMCLZAA-1040 2023/10/31 start {
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import android.util.Log;
import android.text.TextUtils;
//TN modify for bug VFFASMCLZAA-1040 2023/10/31 start }

import java.util.List;
import java.util.function.Consumer;

public class Utils {

    private static Boolean sUseQsMediaPlayer = null;

    /**
     * Allows lambda iteration over a list. It is done in reverse order so it is safe
     * to add or remove items during the iteration.  Skips over null items.
     */
    public static <T> void safeForeach(List<T> list, Consumer<T> c) {
        for (int i = list.size() - 1; i >= 0; i--) {
            T item = list.get(i);
            if (item != null) {
                c.accept(item);
            }
        }
    }

    .....

    /**
     * Gets the {@link R.dimen#status_bar_header_height_keyguard}.
     */
    public static int getStatusBarHeaderHeightKeyguard(Context context) {
        final int statusBarHeight = SystemBarUtils.getStatusBarHeight(context);
        final DisplayCutout cutout = context.getDisplay().getCutout();
        final int waterfallInsetTop = cutout == null ? 0 : cutout.getWaterfallInsets().top;
        final int statusBarHeaderHeightKeyguard = context.getResources()
                .getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard);
        return Math.max(statusBarHeight, statusBarHeaderHeightKeyguard + waterfallInsetTop);
    }

    /**
     * @author:xin.wang
     * @deprecated TN modify for bug VFFASMCLZAA-1040
     * @result true->FastCharge false->Charge
     */
    public static boolean isFastCharge(){
        final String CHARGING_VOLTAGE = "/sys/class/power_supply/mtk-master-charger/voltage_now";
        String result = readFile(CHARGING_VOLTAGE);
        if (!TextUtils.isEmpty(result)){
            float currentCharVol = (float) (Float.parseFloat(result) / 1000.0);
            if (currentCharVol > 6.0){
                return true;
            }else {
                return false;
            }
        }
        return false;
    }

    public static String readFile(final String filepath) {
        File file = new File(filepath);
        if (!file.exists()) {
            return null;
        }
        String content = null;
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            byte[] buffer = new byte[(int) file.length()];
            int length;
            while ((length = fileInputStream.read(buffer)) != -1) {
                byte[] result = new byte[length];
                System.arraycopy(buffer, 0, result, 0, length);
                content = new String(result);
                break;
            }
        } catch (Exception e) {
            return null;
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException e) {
                Log.d("Utils", "readFile: " + e.getMessage());
            }
        }
        return content;
    }
}

http://www.niftyadmin.cn/n/5229973.html

相关文章

ARM安全架构——为复杂软件提供保护

目录 一、概述 二、栈溢出和执行权限 三、面向返回的编程ROP 四、面向跳转的编程(JOP) 五、将这些技术应用于实际代码 七、检查你的知识

iPhone苹果手机如何将词令网页添加到苹果iPhone手机桌面快捷打开?

iPhone苹果手机如何将词令网页添加到苹果iPhone手机桌面快捷打开&#xff1f; 1、在iPhone苹果手机上找到「Safari浏览器」,并点击打开&#xff1b; 2、打开Safari浏览器后&#xff0c;输入词令官方网站地址&#xff1a;ciling.cn ; 3、打开词令官网后&#xff0c;点击Safari…

2022年高校大数据挑战赛B题图像信息隐藏求解全过程论文及程序

2022年高校大数据挑战赛 B题 图像信息隐藏 原题再现&#xff1a; 互联网的快速发展&#xff0c;给图像、视频的传播方式带来巨大变化。图像作为媒体的重要载体&#xff0c;每天有大量的原创图像公开在互联网上&#xff0c;如何保护图像版权的同时不破坏原始的图像一直是图像处…

Node.js【文件系统模块、路径模块 、连接 MySQL、nodemon、操作 MySQL】(三)-全面详解(学习总结---从入门到深化)

目录 Node.js 文件系统模块&#xff08;二&#xff09; Node.js 文件系统模块&#xff08;三&#xff09; Node.js 文件系统模块&#xff08;四&#xff09; Node.js 路径模块 Node.js 连接 MySQL Node.js nodemon Node.js 操作 MySQL Node.js 应用 Node.js 文件系统模块…

数字孪生3D场景开发工具:弥补不足,开拓全新可能

随着数字化时代的来临&#xff0c;越来越多的企业和行业开始探索数字孪生技术的应用。数字孪生是指通过数字技术将现实世界中的物体、场景等复制到虚拟世界中&#xff0c;以实现实时监测、预测和优化。然而&#xff0c;在数字孪生的发展过程中&#xff0c;一些不足也逐渐浮现。…

使用C#和HtmlAgilityPack打造强大的Snapchat视频爬虫

概述 Snapchat作为一款备受欢迎的社交媒体应用&#xff0c;允许用户分享照片和视频。然而&#xff0c;由于其特有的内容自动消失特性&#xff0c;爬虫开发面临一些挑战。本文将详细介绍如何巧妙运用C#和HtmlAgilityPack库&#xff0c;构建一个高效的Snapchat视频爬虫。该爬虫能…

Python实现特征降维--主成分分析 (PCA)

前言 主成分分析是一个重要的线性变换方法&#xff0c;能够将数据从高维降到低维&#xff0c;这篇文章就是主要介绍如何使用PCA实现数据降维 主成分分析 (PCA) 代码中主要是包括了生成随机数、定义PCA函数以及应用PCA。 from sklearn.decomposition import PCA import nump…

NoSQL 数据建模错误会降低性能

数据建模错误是破坏性能的最简单方法之一。当您使用 NoSQL 时&#xff0c;特别容易搞砸&#xff0c;&#xff08;讽刺的是&#xff09;NoSQL 往往用于对性能最敏感的工作负载。NoSQL 数据建模最初可能看起来非常简单&#xff1a;只需对数据进行建模以适应应用程序的访问模式。但…