Andrioid T 实现充电动画(2)

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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/207286.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安装tensorflow tensorboardX

安装tensorflow、tensorflow_gpu 安装这两者的方法是一样的&#xff0c;只是命令不同&#xff0c;根据自己的需要对应修改名称即可。 不使用镜像会超时或者中断错误。 使用镜像安装tensorflow_gpu版本 我这里安装的是2.12.0版本&#xff0c;你可以根据自己的CUDA版本选择合适的…

excel+requests管理测试用例接口自动化框架

背景&#xff1a; 某项目有多个接口&#xff0c;之前使用的unittest框架来管理测试用例&#xff0c;将每个接口的用例封装成一个py文件&#xff0c;接口有数据或者字段变动后&#xff0c;需要去每个py文件中找出变动的接口测试用例&#xff0c;维护起来不方便&#xff0c;为了…

B026-MySQL基础

目录 数据库概述数据库概念数据库的由来和发展常见的关系型数据库服务器&#xff08;DBMS&#xff09;SQL概述表的概念 数据库的安装与配置安装启动和连接MySQL启动MySQL服务连接MySQL MySQL图形化管理软件-Navicat数据库安装失败解决方案 MySQL数据库操作数据库操作和存储引擎…

实验五 C语言函数程序设计习题 (使用函数计算两点间的距离,请编写函数fun,使用函数输出字符矩阵,使用函数求最大公约数和最小公倍数)

1. 使用函数计算两点间的距离&#xff1a;给定平面任意两点坐标(x1,y1)和(x2,y2)&#xff0c;求这两点之间的距离(保留2位)小数。要求定义和调用dist(x1,y1,x2,y2)计算两点间的距离。坐标中两点坐标之间的距离公式如下&#xff1a; #include <stdio.h> #include <math…

再探Java集合系列—HashMap

前面我们已经针对LinkedList和ArrayList的底层原理进行了具体研究讨论&#xff0c;大家可以跳链接阅读哦~ 再探Java集合系列—ArrayList-CSDN博客 再探Java集合系列—LinkedList-CSDN博客 HashMap有哪些特征呢&#xff1f; value可以重复&#xff0c;key不能重复&#xff0c…

【C++干货铺】继承 | 多继承 | 虚继承

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 继承的概念及定义 继承的概念 继承的定义 继承基类成员访问方式的变化 基类和派生类的赋值转化 继承中的作用域 派生类的默认成员函数 构造函数 拷贝构造…

解决Flutter运行报错Could not run build/ios/iphoneos/Runner.app

错误场景 更新了IOS的系统版本为最新的17.0, 运行报以下错误 Launching lib/main.dart on iPhone in debug mode... Automatically signing iOS for device deployment using specified development team in Xcode project: GN3DCAF71C Running Xcode build... Xcode build d…

羊大师分析,鲜羊奶对健康的影响与作用

羊大师分析&#xff0c;鲜羊奶对健康的影响与作用 你是否曾经听到过“羊奶比牛奶更健康”的说法&#xff1f;而鲜羊奶作为最纯正的羊奶形式&#xff0c;其营养价值更是不可小觑。除了拥有传统奶类所包含的营养成分外&#xff0c;鲜羊奶还含有更多人体必需的氨基酸和微量元素&a…

12.1_黑马Redis实战篇Redis优化秒杀Redis消息队列实现异步秒杀

目录 实战篇22 实战篇23 实战篇24 实战篇25 实战篇26 实战篇27 实战篇28 实战篇29 实战篇30 实战篇22 将任务分布给不同的线程去做&#xff0c;可以加快程序运行速度。 放到lua脚本&#xff0c;保证原子性。同时&#xff0c;这样的优化&#xff0c;可以减轻数据库的压…

《尚品甄选》:后台系统——商品管理,对商品数据进行维护(debug一遍)

文章目录 一、表结构介绍二、列表查询三、添加功能(复杂)3.1 加载品牌数据3.2 加载商品单元数据3.3 加载商品规格数据3.4 保存商品数据 四、修改功能4.1 查询商品详情4.2 保存修改数据 五、删除商品六、商品审核七、商品上下架 一、表结构介绍 商品管理就是对电商项目中所涉及…

基于H5“汉函谷关起点新安县旅游信息系统”设计与实现

目 录 摘 要 1 ABSTRACT 2 第1章 绪论 3 1.1 系统开发背景及意义 3 1.2 系统开发的目标 3 第2章 主要开发技术介绍 5 2.1 H5技术介绍 5 2.2 Visual Studio 技术介绍 5 2.3 SQL Server数据库技术介绍 6 第3章 系统分析与设计 7 3.1 可行性分析 7 3.1.1 技术可行性 7 3.1.2 操作…

办公软件PDF转换工具 - Bruce的PDF工具pdftool

Bruce的PDF工具 - 办公软件PDF转换工具 - pdftool&#xff0c;支持&#xff1a; 1、图片转PDF&#xff0c;支持图片自动压缩&#xff0c;可预览图片 2、合并PDF&#xff0c;支持多个PDF合并成一个PDF 3、PDF转图片&#xff0c;PDF的每页转成一张图片 4、OFD转PDF&#xff0c;O…

Postman:专业API测试工具,提升Mac用户体验

如果你是一名开发人员或测试工程师&#xff0c;那么你一定知道Postman。这是一个广泛使用的API测试工具&#xff0c;适用于Windows、Mac和Linux系统。今天&#xff0c;我们要重点介绍Postman的Mac版本&#xff0c;以及为什么它是你进行API测试的理想选择。 一、强大的功能和易…

honle电源维修UV电源控制器EVG EPS40C-HMI

好乐UV电源控制器维修&#xff1b;honle控制器维修&#xff1b;UV电源维修MUC-Steuermodul 2 LΛmpen D-82166 主要维修型号&#xff1a; EVG EPS 60/120、EVG EPS 100、EVG EPS200、EVG EPS 220、EVG EPS 340、EVG EPS40C-HMI、EVG EPS60 HONLE好乐uv电源维修故障包括&#…

2023年第十二届数学建模国际赛小美赛B题工业表面缺陷检测求解分析

2023年第十二届数学建模国际赛小美赛 B题 工业表面缺陷检测 原题再现&#xff1a; 金属或塑料制品的表面缺陷不仅影响产品的外观&#xff0c;还可能对产品的性能或耐久性造成严重损害。自动表面异常检测已经成为一个有趣而有前景的研究领域&#xff0c;对视觉检测的应用领域有…

智能优化算法应用:基于平衡优化器算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于平衡优化器算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于平衡优化器算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.平衡优化器算法4.实验参数设定5.算法结果…

Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 构建可移植的计算机视觉环境 文章目录 前言引言简介&#xff1a;目的和重要性&#xff1a; 深入理解Docker和OpenCVDocker的基本概念和优势&#xff1a;OpenCV简介和应用领域&#xff1a;…

几个linux指令提升编程效率

history history命令是Linux/Unix系统中的一个常用命令&#xff0c;用于查看当前用户在命令行中执行过的命令历史记录。该命令允许用户查看、搜索、编辑和执行之前执行过的命令&#xff0c;为用户提供了方便、快捷的操作方式。 查看历史命令&#xff1a; history查看最近n条…

nginx三种虚拟主机的配置(IP,端口,域名)

准备工作&#xff1a; [rootbogon ~]# mkdir -p /data/nginx{1..3} #-p是用于递归创建使用 [rootbogon ~]# echo "hello nginx1" > /data/nginx1/index.html [rootbogon ~]# echo "hello nginx2" > /data/nginx2/index.html [rootbogon ~]# echo &q…

adb环境搭建(adb下载与安装)

文章目录 前言一、adb下载二、adb安装1.将下载的安装包解压缩2.将解压缩后的文件夹放到自己想存放的目录下&#xff08;不要放到带有中文的目录下&#xff09;——我这放到D盘根目录下3.配置环境变量3.1.鼠标放到 "此电脑"→鼠标右击→选择属性3.2.点击 "高级系…