当前位置: 首页 > news >正文

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.KeyguardChargeAnimationViewxmlns: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"><ImageViewandroid: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" /><ImageViewandroid: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" /><RelativeLayoutandroid: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"><LinearLayoutandroid:id="@+id/charge_battery"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:id="@+id/charge_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="1dp"android:layout_marginRight="3dp" /><TextViewandroid: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><TextViewandroid: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() {@Overridepublic void run() {anim2hide();}};@Overridepublic 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, intbatteryLevel, 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()){@Overridepublic 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() {@Overridepublic 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) {@Overridepublic 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 necessaryhandleHide();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 startprivate KeyguardManager mKeyguardManager;//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 end@Injectpublic 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 startmKeyguardManager = (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 startfilter.addAction(Intent.ACTION_POWER_CONNECTED);filter.addAction(Intent.ACTION_POWER_DISCONNECTED);//TN modify for bug VFFASMCLZAA-1040 by xin.wang 2023/10/30 endmBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler);....}....@Overridepublic 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;}
}

相关文章:

Andrioid T 实现充电动画(2)

Andrioid T 实现充电动画&#xff08;2&#xff09; 以MTK平台为例&#xff0c;实现充电动画 效果图 资源包 修改文件清单 system/vendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/prize_charge_layout.xmlsystem/vendor/mediatek/proprietary/packages/ap…...

静态方法和属性的经典使用-单例设计模式

单例设计模式 一、设计模式二、单例模式1、饿汉式2、懒汉式3、区别 单例设计模式是静态方法和属性的经典使用。 一、设计模式 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱&#xff0c;不同的棋局&…...

TCP七层协议

物理层 中间的物理链接可以是光缆、电缆、双绞线、无线电波。中间传的是电信号&#xff0c;即010101...这些二进制位。 比特(bit)是二进制&#xff08;Binary Digit&#xff09;的简称&#xff0c;电脑所有的信息都是二进制的&#xff0c;就是0和1组成的。 数据链路层 早期…...

规则引擎Drools使用,0基础入门规则引擎Drools(五)实战+决策表

文章目录 系列文章索引十、个人所得税计算器实战1、名词解释2、计算规则3、实现步骤 十一、信用卡申请实战1、计算规则2、实现 十二、保险产品准入规则实战1、决策表2、基于决策表的入门案例3、保险产品规则介绍4、实现步骤5、资料 系列文章索引 规则引擎Drools使用&#xff0…...

Java后端开发——MVC商品管理程序

Java后端开发——MVC商品管理程序 本篇文章内容主要有下面几个部分&#xff1a; MVC架构介绍项目环境搭建商品管理模块Servlet代码重构BaseServlet文件上传 MVC 是模型-视图-控制器&#xff08;Model-View-Controller&#xff09;&#xff0c;它是一种设计模式&#xff0c;也…...

【隐私计算】VOLE (Vector Oblivious Linear Evaluation)学习笔记

近年来&#xff0c;VOLE&#xff08;向量不经意线性评估&#xff09;被用于构造各种高效安全多方计算协议&#xff0c;具有较低的通信复杂度。最近的CipherGPT则是基于VOLE对线性层进行计算。 1 VOLE总体设计 VOLE的功能如下&#xff0c;VOLE发送 Δ \Delta Δ和 b b b给send…...

国产linux单用户模式破解无密码登陆 (麒麟系统用户登录密码遗忘解决办法)

笔者手里有一批国产linu系统&#xff0c;目前开始用在日常的工作生产环境中&#xff0c;我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux&#xff0c;统信UOS等&#xff0c;基本都是基于debian再开发的linux。 问题描述&#xff1a; 因为…...

GPT市场将取代插件商店 openAI已经关闭plugins申请,全部集成到GPTs(Actions)来连接现实世界,可以与物理世界互动了。

Actions使用了plugins的许多核心思想&#xff0c;也增加了新的特性。 ChatGPT的"Actions"与"Plugins"是OpenAI在GPT模型中引入的两种不同的功能扩展机制。这两种机制的目的是增强模型的功能&#xff0c;使其能够处理更多样化的任务和请求。下面是对两者的比…...

PHP定义的变量 常量 静态变量等储存在内存什么位置?

在 PHP 中&#xff0c;变量、常量和静态变量都存储在内存中。它们的存储位置和生命周期有所不同。 变量&#xff1a;PHP 中的变量是动态类型的&#xff0c;它们的值和类型可以随时改变。当 PHP 脚本执行时&#xff0c;会在内存中分配一块空间来存储变量的值&#xff0c;这个空…...

C#中GDI+绘图应用(柱形图、折线图和饼形图)

目录 一、柱形图 1.示例源码 2.生成效果 二、折线图 1.示例源码 2.生成效果 三、饼形图 1.示例源码 2.生成效果 GDI绘制的一些常用的图形&#xff0c;其中包括柱形图、折线图和饼形图。 一、柱形图 柱形图也称为条形图&#xff0c;是程序开发中比较常用的一种图表技术…...

连锁零售企业如何提高异地组网的稳定性?

随着数字化时代的到来&#xff0c;连锁零售企业面临着日益复杂和多样化的网络挑战。连锁零售企业是在不同地理位置拥有分支机构和零售店&#xff0c;可能同城或异地&#xff0c;需要确保各个地点之间的网络连接稳定和可靠。但由于不同地区的网络基础设施差异、网络延迟和带宽限…...

如何靠掌握自己的大数据打破信息流的壁垒?

在当今数字化时代&#xff0c;打造自己的私域流量已经成为商家乃至获取竞争优势的关键手段之一。通过掌握自己的大数据&#xff0c;可以更好地了解用户需求和市场趋势&#xff0c;优化产品和服务&#xff0c;从而打破信息流的壁垒。本文将就如何通过打造自己的私域流量并掌握大…...

LabVIEW绘制带有多个不同标尺的波形图

LabVIEW绘制带有多个不同标尺的波形图 通过在同一波形图上使用多个轴&#xff0c;可以使用不同的标尺绘制数据。请按照以下步骤操作。 将波形图或图表控件放在前面板上。 1. 右键点击您要创建多个标尺的轴&#xff0c;然后选择复制标尺。例如&#xff0c;如果要为一个…...

Oracle行转列,列转行使用实例

-----1.行转换为列 select a.fworkcenter as 车间,F1||-数量 as 类型, fspec as 规格 ,ftype as 前缀 , to_char(fdate,YYYY-MM-dd) as 日期, (case when a.fcode in (900,901) then to_char(fcount,fm90.990) else cast(fcount as varchar(20)) end) 值 , …...

056-第三代软件开发-软件打包

第三代软件开发-软件打包 文章目录 第三代软件开发-软件打包项目介绍软件打包1 下载 linuxdepoyqt 工具2 安装 linuxdepoyqt3 qmake配置4 打包程序 总结 关键字&#xff1a; Qt、 Qml、 linuxdeployqt、 Ubuntu、 AppImage 项目介绍 欢迎来到我们的 QML & C 项目&…...

C++相关闲碎记录(2)

1、误用shared_ptr int* p new int; shared_ptr<int> sp1(p); shared_ptr<int> sp2(p); //error // 通过原始指针两次创建shared_ptr是错误的shared_ptr<int> sp1(new int); shared_ptr<int> sp2(sp1); //ok 如果对C相关闲碎记录(1)中记录的shar…...

如何快速搭建一个大模型?简单的UI实现

&#x1f525;博客主页&#xff1a;真的睡不醒 &#x1f680;系列专栏&#xff1a;深度学习环境搭建、环境配置问题解决、自然语言处理、语音信号处理、项目开发 &#x1f498;每日语录&#xff1a;相信自己&#xff0c;一路风景一路歌&#xff0c;人生之美&#xff0c;正在于…...

国家开放大学 平时作业 测试题 训练

试卷代号&#xff1a;1340 古代小说戏曲专题 参考试题&#xff08;开卷&#xff09; 一、选择&#xff08;每题1分&#xff0c;共10分&#xff09; 1.下列作品中属于唐传奇的是( )。 A.《公孙九娘》 B.《观音作别》 C《碾玉观音》 …...

后端防止重复提交相同数据处理方式(Redis)

使用AOP注解处理接口幂等性&#xff0c;默认禁止同一用户在上次提交未果后10秒内又重复提交 在原先的sameUrlData的注解上进行了copy新建优化&#xff0c;使用redis去setnx的参数视项目使用点而调整&#xff0c;不一定是每个项目都适合这种取参形式。 源码如下: package com…...

最小栈[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 设计一个支持push&#xff0c;pop&#xff0c;top操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现MinStack类: MinStack()初始化堆栈对象。 void push(int val)将元素val推入堆栈。 void pop()删除堆栈顶部的元素。 in…...

Oracle(2-9) Oracle Recovery Manager Overview and Configuration

文章目录 一、基础知识1、User Backup VS RMAN2、Restoring &Recovering DB 还原&恢复数据库3、Recovery Manager Features 管理恢复功能4、RMAN Components RMAN组件5、Repository1: Control File 存储库1:控制文件6、Channel Allocation 通道道分配7、Media Manageme…...

滑动验证码

先上图 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>滑动验证码</title><style>* {margin: 0;padding: 0;}.box {position: relative;width: 375px;margin: 100px a…...

数据爬取+可视化实战_告白气球_词云展示----酷狗音乐

一、前言 歌词上做文本分析&#xff0c;数据存储在网页上&#xff0c;需要爬取数据下来&#xff0c;词云展示在工作中也变得日益重要&#xff0c;接下来将数据爬虫与可视化结合起来&#xff0c;做个词云展示案例。 二、代码 # -*- coding:utf-8 -*- # 酷狗音乐 通过获取每首歌…...

rkmedia_vi_get_frame_test.c 代码解析

使用示例&#xff1a; 录像&#xff1a; rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12 然后用yuvplayer.exe可以播放。 录像10帧&#xff1a; rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12 -c 10 解析代码&#xff1a; #include <as…...

探究Kafka原理-3.生产者消费者API原理解析

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…...

Linux系统iptables扩展

目录 一. iptables规则保存 1. 导出规则保存 2. 自动重载规则 ①. 当前用户生效 ②. 全局生效 二. 自定义链 1. 新建自定义链 2. 重命名自定义链 3. 添加自定义链规则 4. 调用自定义链规则 5. 删除自定义链 三. NAT 1. SNAT 2. DNAT 3. 实验 ①. 实验要求 ②. …...

Openwrt 系统安装 插件名称与中文释义

系统镜像 当时是去官网找对应的&#xff0c;但是作为门外汉&#xff0c;想简单&#xff0c;可以试试这个网站 插件 OpenWrt/Lede全部插件列表功能注释...

[原创]Delphi的SizeOf(), Length(), 动态数组, 静态数组的关系.

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…...

C++(20):bind_front

C(11)&#xff1a;bind_c11 bind_风静如云的博客-CSDN博客 提供了方法来绑定函数参数的方法。 C20提供了bind_front用于简化这个绑定。 #include <iostream> #include <functional> using namespace std;void func1(int d1, int d2) {cout<<__func__<&l…...

【spring】bean的后处理器

目录 一、作用二、常见的bean后处理器2.1 AutowiredAnnotationBeanPostProcessor2.1.1 说明2.1.2 代码示例2.1.3 截图示例 2.2 CommonAnnotationBeanPostProcessor2.2.1 说明2.2.2 代码示例2.2.3 截图示例 2.3 ConfigurationPropertiesBindingPostProcessor2.3.1 说明2.3.2 代码…...