Andrioid T 实现充电动画(2)

news2024/11/16 13:46:43

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.coloradmin.cn/o/1272709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iptables防火墙之SNAT与DNET

NAT 1.SNAT&#xff1a;让内网可以访问外网 2.DNAT&#xff1a;让外网可以访问到内网的机器 网关服务器&#xff0c;要开启路由功能 内核功能&#xff1a; sysctl -a 列出所有参数 内核参数&#xff0c;然后grep可以查看到默认的内核参数 内核参数配置文件 /etc/sysctl.…

时序预测 | Python实现GA-TCN-LSTM遗传算法-时间卷积神经网络-长短期记忆网络时间序列预测

时序预测 | Python实现GA-TCN-LSTM遗传算法-时间卷积神经网络-长短期记忆网络时间序列预测 目录 时序预测 | Python实现GA-TCN-LSTM遗传算法-时间卷积神经网络-长短期记忆网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 使用先进的机器学习技术和优化算法…

window10家庭版中文转专业版流程

1.确认当前为家庭中文版 2.用管理员权限打开cmd窗口 3.输入 dism /online /get-targeteditions &#xff0c;查询当前支持的升级的版本 4.专业版密钥&#xff1a;VK7JG-NPHTM-C97JM-9MPGT-3V66T 5.changepk.exe /productkey VK7JG-NPHTM-C97JM-9MPGT-3V66T

微服务--07--Seata 分布式事务

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 分布式事务1.认识Seata2.部署TC服务2.1.准备数据库表2.2.准备配置文件2.3.Docker部署 3.微服务集成Seata3.1.引入依赖3.2.改造配置3.3.添加数据库表3.4.测试 分布式…

事务级 REST API 在网络管理中的应用

什么是REST API&#xff1f; REST&#xff08;Representational State Transfer&#xff0c;也称RESTful&#xff09;API是一种架构风格&#xff0c;用于构建网络应用程序和服务之间的通信&#xff0c;是基于HTTP协议的一种应用程序接口。它提供了一组规范和约定&#xff0c;使…

【每日一坑】KiCAD导Gerber 文件

第一&#xff0c;软件版本 第二、操作选择注意点 第三步&#xff0c;那个坑。。。 不知道什么原因&#xff0c;这第二个框里会选其他不必要得一些东西&#xff0c;导致最终光绘是废的&#xff1b; 一定切记只选edge.cut就好了。 最后&#xff0c;上Gerber图&#xff0c;还有一…

Java数据结构之《顺序查找》问题

一、前言&#xff1a; 这是怀化学院的&#xff1a;Java数据结构中的一道难度中等偏下的一道编程题(此方法为博主自己研究&#xff0c;问题基本解决&#xff0c;若有bug欢迎下方评论提出意见&#xff0c;我会第一时间改进代码&#xff0c;谢谢&#xff01;) 后面其他编程题只要我…

位图和布隆过滤器(C++)

位图和布隆过滤器 一、位图1. 引入2. 概念3. 代码实现setreset完整代码 4. 位图的应用 二、布隆过滤器1. 引入2. 概念3. 逻辑结构4. 特点5. 代码实现6. 布隆过滤器的应用 三、哈希切割 一、位图 1. 引入 当面对海量数据需要处理时&#xff0c;内存不足以加载这些数据&#xf…

网络基础_1

目录 网络基础 协议 协议分层 OSI七层模型 网络传输的基本流程 数据包的封装和分用 IP地址和MAC地址 网络基础 网络就是不同的计算机之间可以进行通信&#xff0c;前面我们学了同一台计算机之间通信&#xff0c;其中有进程间通信&#xff0c;前面学过的有管道&#xff…

C++ 学习之函数成员指针的一个小细节

看看下面的代码&#xff0c;你能看出错误吗 class A { public:void fun(){}}; int main() {A a;void (A:: * p)() &A::fun;(*p)(); } 这段代码在调用成员函数时存在问题。正确的方式是使用对象来调用成员函数&#xff0c;而不是通过指针。以下是修正后的代码&#xff1a…

java学校高校运动会报名信息管理系统springboot+jsp

课题研究方案&#xff1a; 结合用户的使用需求&#xff0c;本系统采用运用较为广泛的Java语言&#xff0c;springboot框架&#xff0c;HTML语言等关键技术&#xff0c;并在idea开发平台上设计与研发创业学院运动会管理系统。同时&#xff0c;使用MySQL数据库&#xff0c;设计实…

【数据清洗 | 数据规约】数据类别型数据 编码最佳实践,确定不来看看?

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

1-3、DOSBox环境搭建

语雀原文链接 文章目录 1、安装DOSBox2、Debug进入Debugrdeautq 1、安装DOSBox 官网下载下载地址&#xff1a;https://www.dosbox.com/download.php?main1此处直接下载这个附件&#xff08;内部有8086的DEBUG.EXE环境&#xff09;8086汇编工作环境.rar执行安装DOSBox0.74-wi…

2021年8月18日 Go生态洞察:整合Go的网络体验

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

带大家做一个,易上手的家常炒鸡蛋

想做这道菜 先准备五个鸡蛋 然后将鸡蛋打到碗里面 然后 加小半勺盐 这个看个人喜好 放多少都没问题 不要太咸就好 将鸡蛋搅拌均匀 起锅烧油 油温热了之后 放三个干辣椒进去炒 干辣椒烧黑后 捞出来 味道就留在油里了 然后 倒入鸡蛋液 翻炒 注意翻炒 不要粘锅底 或者 一面糊…

Oracle SQL优化

1、书写顺序和执行顺序 在Oracle SQL中&#xff0c;查询的书写顺序和执行顺序是不同的。 1.1SQL书写顺序如下&#xff1a; SELECTFROMWHEREGROUP BYHAVINGORDER BY 1.2 SQL执行顺序 FROM&#xff1a;数据源被确定&#xff0c;表连接操作也在此步骤完成。 WHERE&#xff1a;对…

防爆执法记录仪、防爆智能安全帽助力海上钻井平台远程可视化监管平台建设

推动远程安全管理&#xff0c;海上钻井"视"界拓新—防爆执法记录仪与防爆智能安全帽的创新应用 在海上钻井作业领域&#xff0c;安全生产一直是萦绕在每一个业者心头的重大课题。由于环境的恶劣及作业的特殊性&#xff0c;一旦发生安全事故&#xff0c;其后果往往极…

【MySQL】视图:简化查询

文章目录 create view … as创建视图更改或删除视图drop view 删除视图replace关键字&#xff1a;更改视图 可更新视图with check option子句&#xff1a;防止行被删除视图的其他优点简化查询减小数据库设计改动的影响使用视图限制基础表访问 create view … as创建视图 把常用…

Scrapy框架中间件(一篇文章齐全)

1、Scrapy框架初识&#xff08;点击前往查阅&#xff09; 2、Scrapy框架持久化存储&#xff08;点击前往查阅&#xff09; 3、Scrapy框架内置管道&#xff08;点击前往查阅&#xff09; 4、Scrapy框架中间件 Scrapy 是一个开源的、基于Python的爬虫框架&#xff0c;它提供了…

分支和循环

通常来说&#xff0c;C语言是结构化的程序设计语言&#xff0c;这里的结构包括顺序结构、选择结构、循环结构&#xff0c;C语言能够实现这三种结构&#xff0c;如果我们仔细分析&#xff0c;我们日常生活中所见的事情都可以拆分为这三种结构或者它们的组合。 下面我会仔细讲解我…