国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 11 系統(tǒng)開發(fā)增加低電量彈窗提示 手機 平板 車載 TV 投影 通用

這篇具有很好參考價值的文章主要介紹了Android 11 系統(tǒng)開發(fā)增加低電量彈窗提示 手機 平板 車載 TV 投影 通用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1、PowerUI是系統(tǒng)中控制電量提示的模塊,低電量提醒、低電量關機提醒、高溫關機提醒、省電模式都在其中實現(xiàn)

SystemUIService 中啟動PowerUI

public class SystemUIService extends Service {
 
    @Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
 
        // For debugging RescueParty
        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
            throw new RuntimeException();
        }
 
        if (Build.IS_DEBUGGABLE) {
            // b/71353150 - looking for leaked binder proxies
            BinderInternal.nSetBinderProxyCountEnabled(true);
            BinderInternal.nSetBinderProxyCountWatermarks(1000,900);
            BinderInternal.setBinderProxyCountCallback(
                    new BinderInternal.BinderProxyLimitListener() {
                        @Override
                        public void onLimitReached(int uid) {
                            Slog.w(SystemUIApplication.TAG,
                                    "uid " + uid + " sent too many Binder proxies to uid "
                                    + Process.myUid());
                        }
                    }, Dependency.get(Dependency.MAIN_HANDLER));
        }
    }SystemUIService 啟動時,啟動SystemUIApplicationstartServicesIfNeeded() 來啟動SystemUI的各種服務
  在SystemUIApplication中 啟動PowerUI
  config.xml 中config_systemUIServiceComponents
  <string-array name="config_systemUIServiceComponents" translatable="false">
        <item>com.android.systemui.Dependency$DependencyCreator</item>
        <item>com.android.systemui.util.NotificationChannels</item>
        <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
        <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
        <item>com.android.systemui.recents.Recents</item>
        <item>com.android.systemui.volume.VolumeUI</item>
        <item>com.android.systemui.stackdivider.Divider</item>
        <item>com.android.systemui.SystemBars</item>
        <item>com.android.systemui.usb.StorageNotification</item>
        <item>com.android.systemui.power.PowerUI</item>
        <item>com.android.systemui.media.RingtonePlayer</item>
        <item>com.android.systemui.keyboard.KeyboardUI</item>
        <item>com.android.systemui.pip.PipUI</item>
        <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
        <item>@string/config_systemUIVendorServiceComponent</item>
        <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
        <item>com.android.systemui.LatencyTester</item>
        <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
        <item>com.android.systemui.ScreenDecorations</item>
        <item>com.android.systemui.biometrics.BiometricDialogImpl</item>
        <item>com.android.systemui.SliceBroadcastRelayHandler</item>
        <item>com.android.systemui.SizeCompatModeActivityController</item>
        <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
        <item>com.android.systemui.theme.ThemeOverlayController</item>
    </string-array>
      /**
     * Makes sure that all the SystemUI services are running. If they are already running, this is a
     * no-op. This is needed to conditinally start all the services, as we only need to have it in
     * the main process.
     * <p>This method must only be called from the main thread.</p>
     */
    public void startServicesIfNeeded() {
        String[] names = SystemUIFactory.getInstance().getSystemUIServiceComponents(getResources());
        startServicesIfNeeded(/* metricsPrefix= */ "StartServices", names);
    }
   SystemUIFactorygetSystemUIServiceComponents(Resources resources)
   public String[] getSystemUIServiceComponents(Resources resources) {
          return resources.getStringArray(R.array.config_systemUIServiceComponents);
     }
   private void startServicesIfNeeded(String[] services) {
        if (mServicesStarted) {
            return;
        }
        mServices = new SystemUI[services.length];
 
        if (!mBootCompleted) {
            // check to see if maybe it was already completed long before we began
            // see ActivityManagerService.finishBooting()
            if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
                mBootCompleted = true;
                if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
            }
        }
 
        Log.v(TAG, "Starting SystemUI services for user " +
                Process.myUserHandle().getIdentifier() + ".");
        TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
                Trace.TRACE_TAG_APP);
        log.traceBegin("StartServices");
        final int N = services.length;
        for (int i = 0; i < N; i++) {
            String clsName = services[i];
            if (DEBUG) Log.d(TAG, "loading: " + clsName);
            log.traceBegin("StartServices" + clsName);
            long ti = System.currentTimeMillis();
            Class cls;
            try {
                cls = Class.forName(clsName);
                Object o = cls.newInstance();
                if (o instanceof SystemUI.Injector) {
                    o = ((SystemUI.Injector) o).apply(this);
                }
                mServices[i] = (SystemUI) o;
            } catch(ClassNotFoundException ex){
                throw new RuntimeException(ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }
 
            mServices[i].mContext = this;
            mServices[i].mComponents = mComponents;
            if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
            mServices[i].start();
            log.traceEnd();
 
            // Warn if initialization of component takes too long
            ti = System.currentTimeMillis() - ti;
            if (ti > 1000) {
                Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
            }
            if (mBootCompleted) {
                mServices[i].onBootCompleted();
            }
        }
        Dependency.get(InitController.class).executePostInitTasks();
        log.traceEnd();
        final Handler mainHandler = new Handler(Looper.getMainLooper());
        Dependency.get(PluginManager.class).addPluginListener(
                new PluginListener<OverlayPlugin>() {
                    private ArraySet<OverlayPlugin> mOverlays = new ArraySet<>();
 
                    @Override
                    public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                StatusBar statusBar = getComponent(StatusBar.class);
                                if (statusBar != null) {
                                    plugin.setup(statusBar.getStatusBarWindow(),
                                            statusBar.getNavigationBarView(), new Callback(plugin));
                                }
                            }
                        });
                    }
 
                    @Override
                    public void onPluginDisconnected(OverlayPlugin plugin) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mOverlays.remove(plugin);
                                Dependency.get(StatusBarWindowController.class).setForcePluginOpen(
                                        mOverlays.size() != 0);
                            }
                        });
                    }
 
                    class Callback implements OverlayPlugin.Callback {
                        private final OverlayPlugin mPlugin;
 
                        Callback(OverlayPlugin plugin) {
                            mPlugin = plugin;
                        }
 
                        @Override
                        public void onHoldStatusBarOpenChange() {
                            if (mPlugin.holdStatusBarOpen()) {
                                mOverlays.add(mPlugin);
                            } else {
                                mOverlays.remove(mPlugin);
                            }
                            mainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    Dependency.get(StatusBarWindowController.class)
                                            .setStateListener(b -> mOverlays.forEach(
                                                    o -> o.setCollapseDesired(b)));
                                    Dependency.get(StatusBarWindowController.class)
                                            .setForcePluginOpen(mOverlays.size() != 0);
                                }
                            });
                        }
                    }
                }, OverlayPlugin.class, true /* Allow multiple plugins */);
 
        mServicesStarted = true;
    }

2、PowerUI 電量的分析

public void start() {
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
mWarnings = Dependency.get(WarningsUI.class);
mEnhancedEstimates = Dependency.get(EnhancedEstimates.class);
mLastConfiguration.setTo(mContext.getResources().getConfiguration());
 
ContentObserver obs = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
updateBatteryWarningLevels();
}
};
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, obs, UserHandle.USER_ALL);
updateBatteryWarningLevels();
mReceiver.init();
 
// Check to see if we need to let the user know that the phone previously shut down due
// to the temperature being too high.
showWarnOnThermalShutdown();
 
// Register an observer to configure mEnableSkinTemperatureWarning and perform the
// registration of skin thermal event listener upon Settings change.
resolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.SHOW_TEMPERATURE_WARNING),
false /*notifyForDescendants*/,
new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
doSkinThermalEventListenerRegistration();
}
});
// Register an observer to configure mEnableUsbTemperatureAlarm and perform the
// registration of usb thermal event listener upon Settings change.
resolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.SHOW_USB_TEMPERATURE_ALARM),
false /*notifyForDescendants*/,
new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
doUsbThermalEventListenerRegistration();
}
});
initThermalEventListeners();
mCommandQueue.addCallback(this);
}
 
@VisibleForTesting
final class Receiver extends BroadcastReceiver {
 
private boolean mHasReceivedBattery = false;
 
public void init() {
// Register for Intent broadcasts for...
IntentFilter filter = new IntentFilter();
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_SWITCHED);
mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler);
// Force get initial values. Relying on Sticky behavior until API for getting info.
if (!mHasReceivedBattery) {
// Get initial state
Intent intent = mContext.registerReceiver(
null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)
);
if (intent != null) {
onReceive(mContext, intent);
}
}
}
 
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
ThreadUtils.postOnBackgroundThread(() -> {
if (mPowerManager.isPowerSaveMode()) {
mWarnings.dismissLowBatteryWarning();
}
});
} else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
mHasReceivedBattery = true;
final int oldBatteryLevel = mBatteryLevel;
mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);
final int oldBatteryStatus = mBatteryStatus;
mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
BatteryManager.BATTERY_STATUS_UNKNOWN);
final int oldPlugType = mPlugType;
mPlugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 1);
final int oldInvalidCharger = mInvalidCharger;
mInvalidCharger = intent.getIntExtra(BatteryManager.EXTRA_INVALID_CHARGER, 0);
mLastBatteryStateSnapshot = mCurrentBatteryStateSnapshot;
 
final boolean plugged = mPlugType != 0;
final boolean oldPlugged = oldPlugType != 0;
 
int oldBucket = findBatteryLevelBucket(oldBatteryLevel);
int bucket = findBatteryLevelBucket(mBatteryLevel);
 
if (DEBUG) {
Slog.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
+ " .. " + mLowBatteryReminderLevels[0]
+ " .. " + mLowBatteryReminderLevels[1]);
Slog.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
Slog.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
Slog.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
Slog.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
Slog.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
}
 
mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
Slog.d(TAG, "showing invalid charger warning");
mWarnings.showInvalidChargerWarning();
return;
} else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
mWarnings.dismissInvalidChargerWarning();
} else if (mWarnings.isInvalidChargerWarningShowing()) {
// if invalid charger is showing, don't show low battery
if (DEBUG) {
Slog.d(TAG, "Bad Charger");
}
return;
}
// Show the correct version of low battery warning if needed
if (mLastShowWarningTask != null) {
mLastShowWarningTask.cancel(true);
if (DEBUG) {
Slog.d(TAG, "cancelled task");
}
}
//
mLastShowWarningTask = ThreadUtils.postOnBackgroundThread(() -> {
maybeShowBatteryWarningV2(
plugged, bucket);
});
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
mScreenOffTime = SystemClock.elapsedRealtime();
} else if (Intent.ACTION_SCREEN_ON.equals(action)) {
mScreenOffTime = -1;
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mWarnings.userSwitched();
} else {
Slog.w(TAG, "unknown intent: " + intent);
}
}
}PowerUIstart()方法中啟動廣播監(jiān)聽電量變化
mLastShowWarningTask = ThreadUtils.postOnBackgroundThread(() -> {
maybeShowBatteryWarningV2(
plugged, bucket);
});
來判斷是否開啟低電量警告
protected void maybeShowBatteryWarningV2(boolean plugged, int bucket) {
final boolean hybridEnabled = mEnhancedEstimates.isHybridNotificationEnabled();
final boolean isPowerSaverMode = mPowerManager.isPowerSaveMode();
// Stick current battery state into an immutable container to determine if we should show
// a warning.
if (DEBUG) {
Slog.d(TAG, "evaluating which notification to show");
}
if (hybridEnabled) {
if (DEBUG) {
Slog.d(TAG, "using hybrid");
}
Estimate estimate = refreshEstimateIfNeeded();
mCurrentBatteryStateSnapshot = new BatteryStateSnapshot(mBatteryLevel, isPowerSaverMode,
plugged, bucket, mBatteryStatus, mLowBatteryReminderLevels[1],
mLowBatteryReminderLevels[0], estimate.getEstimateMillis(),
estimate.getAverageDischargeTime(),
mEnhancedEstimates.getSevereWarningThreshold(),
mEnhancedEstimates.getLowWarningThreshold(), estimate.isBasedOnUsage(),
mEnhancedEstimates.getLowWarningEnabled());
} else {
if (DEBUG) {
Slog.d(TAG, "using standard");
}
mCurrentBatteryStateSnapshot = new BatteryStateSnapshot(mBatteryLevel, isPowerSaverMode,
plugged, bucket, mBatteryStatus, mLowBatteryReminderLevels[1],
mLowBatteryReminderLevels[0]);
}
mWarnings.updateSnapshot(mCurrentBatteryStateSnapshot);
if (mCurrentBatteryStateSnapshot.isHybrid()) {
maybeShowHybridWarning(mCurrentBatteryStateSnapshot, mLastBatteryStateSnapshot);
} else {
//低電量警告
maybeShowBatteryWarning(mCurrentBatteryStateSnapshot, mLastBatteryStateSnapshot);
}
protected void maybeShowBatteryWarning(
              BatteryStateSnapshot currentSnapshot,
             BatteryStateSnapshot lastSnapshot) {
         final boolean playSound = currentSnapshot.getBucket() != lastSnapshot.getBucket()
                  || lastSnapshot.getPlugged();
  
         if (shouldShowLowBatteryWarning(currentSnapshot, lastSnapshot)) {
              mWarnings.showLowBatteryWarning(playSound);//低電量警告
          } else if (shouldDismissLowBatteryWarning(currentSnapshot, lastSnapshot)) {
              mWarnings.dismissLowBatteryWarning();//去掉低電量警告
          } else {
              mWarnings.updateLowBatteryWarning();
          }
      }
  PowerNotificationWarnings.java的低電量提醒方法
       @Override
      public void showLowBatteryWarning(boolean playSound) {
          Slog.i(TAG,
                  "show low battery warning: level=" + mBatteryLevel
                         + " [" + mBucket + "] playSound=" + playSound);
          mPlaySound = playSound;
          mWarning = true;
          updateNotification();
      }
}

3、增加低電量的彈窗 PowerNotificationWarnings.java的showLowBatteryWarning()方法

import android.app.AlertDialog;
    import android.view.WindowManager;
    import android.content.DialogInterface;
    private AlertDialog mbatteryLowDialog = null;
      // 自定義電池溫度Dialog彈窗
    private void batterylowDialog(String lowbattery) {
        mbatteryLowDialog = new AlertDialog(mContext);
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle(mContext.getResources().getString(
                com.android.internal.R.string.lowbatteryWarning));
        builder.setCancelable(false);
        builder.setMessage(lowbattery);
        builder.setIconAttribute(android.R.attr.alertDialogIcon);
        builder.setPositiveButton(com.android.internal.R.string.batteryLow111,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                        mbatteryLowDialog = null;
                    }
                });
        mbatteryLowDialog = builder.create();
        mbatteryLowDialog.getWindow().setType(
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        if (mbatteryLowDialog != null&& !mbatteryLowDialog.isShowing()) {
            mbatteryLowDialog.show();
        }
 
    }
 
       @Override
      public void showLowBatteryWarning(boolean playSound) {
          Slog.i(TAG,
                  "show low battery warning: level=" + mBatteryLevel
                         + " [" + mBucket + "] playSound=" + playSound);
          mPlaySound = playSound;
          mWarning = true;
          updateNotification();
        + batterylowDialog("低電量")
      }

4、增加低電量提醒的xml資源

主要修改

frameworks/base/core/res/res/values/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    ... ...
    <!-- Shutdown if the battery temperature exceeds (this value * 0.1) Celsius. -->
    <string name="lowbatteryWarning">低電量提醒</integer>
    <!-- add code begin-->
    <string name="batteryLow111">111</integer>
    <!-- add code end-->
    ... ...
</resources>

5、在symbols 文件中添加對應java-symbol方便Framework代碼引用code文章來源地址http://www.zghlxwxcb.cn/news/detail-839966.html

在symbols文件中為全部string,int值注冊,方便Framework層代碼的引用。
frameworks/base/core/res/res/values/symbols.xml
 
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <!-- Private symbols that we need to reference from framework code.  See
       frameworks/base/core/res/MakeJavaSymbols.sed for how to easily generate
       this.
 
       Can be referenced in java code as: com.android.internal.R.<type>.<name>
       and in layout xml as: "@*android:<type>/<name>"
  -->
 
  <!-- add code begin-->
  <java-symbol type="string" name="lowbatteryWarning" />
  <java-symbol type="string" name="batteryLow111" />

到了這里,關于Android 11 系統(tǒng)開發(fā)增加低電量彈窗提示 手機 平板 車載 TV 投影 通用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 關于在Android 11系統(tǒng)手機上請求READ_PHONE_STATE權(quán)限的問題

    起因是因為bugly報錯: 上網(wǎng)查了下,原來在Android11及以上機型上調(diào)用telephonyManager.getNetworkType()需要READ_PHONE_STATE權(quán)限,于是我就在應用啟動時加上了申請該權(quán)限的代碼,并且在調(diào)用getNetworkType()方法的地方加了判斷,如果系統(tǒng)版本大于等于11并且沒有被授予READ_PHONE_STATE權(quán)限,就

    2024年02月12日
    瀏覽(43)
  • 【電量計芯片】鼎盛合分享手機電量顯示電量芯片技術(shù)

    不知道有沒有人會跟我一樣曾經(jīng)有手機電量焦慮癥,電量沒有滿格出門一定會焦慮,電量低于三分之一就已經(jīng)在想要不要充電了,而一旦電量顏色變黃以下我就不敢再玩手機,立即去充電。這種問題我相信肯定不是只有我一個人有,更有甚者看到手機電量的電量槽空了一截就

    2024年02月08日
    瀏覽(24)
  • APP安卓開發(fā)之Android Studio從安裝到創(chuàng)建項目(一鍵解決gradle下載緩慢以及寫代碼沒提示問題,包含如何創(chuàng)建手機模擬器)教程

    APP安卓開發(fā)之Android Studio從安裝到創(chuàng)建項目(一鍵解決gradle下載緩慢以及寫代碼沒提示問題,包含如何創(chuàng)建手機模擬器)教程

    選擇NEXT 選擇NEXT 選擇要安裝的地址,然后選擇NEXT 選擇Install 先啟動剛安裝好的Android Studio 選擇Do not import settings,然后選擇OK 選擇Cancel 先選擇D\\\'ont send,然后選擇NEXT 這里選擇Custom,然后NEXT 選擇Android Studio自帶JDK的安裝位置,然后NEXT 選擇一個自己喜歡的主題顏色,然后NEXT 選

    2024年04月29日
    瀏覽(37)
  • Android11編譯第六彈:user版本增加su+內(nèi)置root用戶

    Android11編譯第六彈:user版本增加su+內(nèi)置root用戶

    問題1:user版本默認不開放root,adb登錄后默認采用system用戶,收緊用戶權(quán)限; 問題2:因為有些功能需要用到root用戶,例如設置網(wǎng)卡地址,網(wǎng)卡開啟和關閉等,因為線上設備user版本沒有root用戶開放,很不方便。采用允許登錄root用戶的方式,登錄時增加密碼驗證。 問題3:默

    2024年01月23日
    瀏覽(42)
  • 如何實現(xiàn)”系統(tǒng)可能不會保存您所做的更改”的彈窗提示

    如何實現(xiàn)”系統(tǒng)可能不會保存您所做的更改”的彈窗提示

    在本文框輸入內(nèi)容,關閉頁面或者刷新頁面時會彈出提示“系統(tǒng)可能不會保存您所做的更改”: 谷歌瀏覽器效果: Safari瀏覽器效果:

    2024年02月07日
    瀏覽(24)
  • IOS手機耗電量測試

    IOS手機耗電量測試

    1. 耗電量原始測試方法 1.1 方法原理: 根據(jù)iPhone手機右上角的電池百分比變化來計算耗電量。 1.2實際操作: 在iOS通用設置中打開電池百分比數(shù)值顯示,然后操作30分鐘,60分鐘,90分鐘,看開始時和結(jié)束時電池百分比數(shù)值的差值。 1.3 優(yōu)缺點分析: 1、電池百分比數(shù)據(jù)非常粗略

    2024年02月06日
    瀏覽(13)
  • android多屏觸摸相關的詳解方案-安卓framework開發(fā)手機車載車機系統(tǒng)開發(fā)課程

    android多屏觸摸相關的詳解方案-安卓framework開發(fā)手機車載車機系統(tǒng)開發(fā)課程

    直播免費視頻課程地址:https://www.bilibili.com/video/BV1hN4y1R7t2/ 在做雙屏相關需求開發(fā)過程中,經(jīng)常會有對兩個屏幕都要求可以正確觸摸的場景。但是目前我們模擬器默認創(chuàng)建的雙屏其實是沒有辦法進行觸摸的 靜態(tài)修改方案 使用命令查看display2即副屏的信息情況 adb shell dumpsys d

    2024年02月11日
    瀏覽(24)
  • 華為主題開發(fā)分享-在windows 11操作系統(tǒng)上識別不到P50等華為手機的解決方案

    華為主題開發(fā)分享-在windows 11操作系統(tǒng)上識別不到P50等華為手機的解決方案

    在開發(fā)華為手機主題時,我們都是采用Them studio進行實際測試,無它,官方工具的“同步”功能實在是好用。一鍵就能將主題推到手機上進行測試,高效方便。 但對于有的老款手機比如p50,在windows 11操作系統(tǒng)上,會遇到無法識別硬件的苦惱。 這里分享下解決方案。 1、首先,

    2024年02月12日
    瀏覽(44)
  • hal深入剖析之a(chǎn)idl實戰(zhàn)-android framework車機車載手機系統(tǒng)開發(fā)

    hal深入剖析之a(chǎn)idl實戰(zhàn)-android framework車機車載手機系統(tǒng)開發(fā)

    這個是hal工程根目錄 接下來要創(chuàng)建aidl的文件存放目錄 注意mkdir -p android/hardware/mytest其實就是包名目錄,即模塊包名就是android.hardware.mytest. 提示:這個如果為了項目的更加好的維護性建議到自己項目目標的vendor下面進行,目前只是為了演示方便,直接在system的hardware下面 創(chuàng)建

    2024年02月19日
    瀏覽(20)
  • Android Framework最難模塊WMS實戰(zhàn)作業(yè)-手機車機系統(tǒng)開發(fā)必備

    Android Framework最難模塊WMS實戰(zhàn)作業(yè)-手機車機系統(tǒng)開發(fā)必備

    0-整體介紹 1-window-container.mp4 窗口層級樹實戰(zhàn)啟動篇 2-displayarea-feature.mp4 窗口層級樹源碼分析相關 3-displayarea-draw-feature.mp4 窗口層級樹繪制實戰(zhàn)1 4-displayarea-draw-leaf.mp4 窗口層級樹繪制實戰(zhàn)2 5-displayarea-draw-leaf-2.mp4 窗口層級樹繪制實戰(zhàn)3 6-displayarea-surfacelayer.mp4 窗口層級樹相關sur

    2024年02月12日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包