日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

adb命令实现一些有趣的功能

發(fā)布時(shí)間:2025/3/15 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 adb命令实现一些有趣的功能 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

下載ADB工具集,手機(jī)連接電腦后,用Windows自帶命令行進(jìn)入ADB工具,輸入以下命令即可免root實(shí)現(xiàn)神奇功能

1.電量顯示:

adb shell content insert --uri content://settings/system --bind name:s:status_bar_show_battery_percent --bind value:i:1

2.全屏沉浸:

adb shell settings put global policy_control immersive.full=*

3.沉浸狀態(tài)欄:

adb shell settings put global policy_control immersive.status=*

4.沉浸導(dǎo)航欄:

adb shell settings put global policy_control immersive.navigation=*

5.我們還可以單獨(dú)控制哪些app不沉浸,例如以下代碼設(shè)置google即時(shí)桌面不沉浸,其他程序沉浸:

adb shell settings put global policy_control immersive.full=apps,-com.google.android.googlequicksearchbox

6.如果想恢復(fù)到正常模式,運(yùn)行下面的代碼:

adb shell settings put global policy_control null

7.截圖命令screencap

adb shell screencap -p /sdcard/screen.png

8.命令行下拉和收縮狀態(tài)欄

adb shell service call statusbar 1 //下拉顯示命令行 adb shell service call statusbar 2 //收縮狀態(tài)欄

在nexus6吧發(fā)現(xiàn)了上面這個(gè)帖子,感謝nexus6吧的機(jī)友,親測可用,很強(qiáng)大,可以正常使用輸入法,使用虛擬按鍵時(shí)從底部上滑即可,比貼吧里那個(gè)使用全能助手隱藏虛擬鍵的方法好些,adb工具用刷機(jī)精靈也可以,我是把第四條和第五條命令綜合一下,nova啟動(dòng)器不隱藏虛擬鍵,其他全部隱藏虛擬鍵,但狀態(tài)欄都不隱藏,指令:

adb shell settings put global policy_control immersive.navigation=apps,-com.teslacoilsw.launcheradb shell settings put global policy_control immersive.navigation=apps,-com.teslacoilsw.launcher,-com.motorola.camera

由于機(jī)友反映打開相機(jī)無法呼出虛擬鍵,今天把指令改進(jìn)了一下,這個(gè)adb指令可以讓nova啟動(dòng)器和moto相機(jī)都不隱藏虛擬鍵,從而解決了隱藏虛擬鍵后打開相機(jī)上滑無法呼出虛擬鍵。

moto z/z play按一下指紋鍵就可以自動(dòng)呼出虛擬鍵,不用上滑呼出的,所以,這種方法還是可以的,不用root,不影響OTA和保修。

(注意:1.adb工具也可以下載刷機(jī)精靈,使用其工具中的adb命令行;2.輸入adb命令時(shí)記得切換到英文;3.apps后面的文件名,可以在手機(jī)上打開,然后去設(shè)置中的正在運(yùn)行的程序中查看,或者下載安裝文件名查看器查看 )

adb shell am 的用法

C:\Users\Administrator>adb shell am usage: am [subcommand] [options]start an Activity: am start [-D] [-W] <INTENT>-D: enable debugging-W: wait for launch to completestart a Service: am startservice <INTENT>send a broadcast Intent: am broadcast <INTENT>start an Instrumentation: am instrument [flags] <COMPONENT>-r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT)-e <NAME> <VALUE>: set argument <NAME> to <VALUE>-p <FILE>: write profiling data to <FILE>-w: wait for instrumentation to finish before returningstart profiling: am profile <PROCESS> start <FILE> stop profiling: am profile <PROCESS> stopstart monitoring: am monitor [--gdb <port>]--gdb: start gdbserv on the given port at crash/ANR<INTENT> specifications include these flags:[-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>][-c <CATEGORY> [-c <CATEGORY>] ...][-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...][--esn <EXTRA_KEY> ...][--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...][-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...][-n <COMPONENT>] [-f <FLAGS>][--grant-read-uri-permission] [--grant-write-uri-permission][--debug-log-resolution][--activity-brought-to-front] [--activity-clear-top][--activity-clear-when-task-reset] [--activity-exclude-from-recents][--activity-launched-from-history] [--activity-multiple-task][--activity-no-animation] [--activity-no-history][--activity-no-user-action] [--activity-previous-is-top][--activity-reorder-to-front] [--activity-reset-task-if-needed][--activity-single-top][--receiver-registered-only] [--receiver-replace-pending][<URI>]

使用實(shí)例:
如啟動(dòng)一個(gè) Activity:

格式:

adb shell am start -n 包名/包名+類名(-n 類名,-a action,-d date,-m MIME-TYPE,-c category,-e 擴(kuò)展數(shù)據(jù),等)。

實(shí)例1:

C:\Users\Administrator>adb shell am start -n com.android.camera/.Camera Starting: Intent { cmp=com.android.camera/.Camera }

實(shí)例2:(帶extra 的 intent)

C:\Users\Administrator>adb shell am start -n com.android.camera/.Camera -e abc hello

Starting: Intent { cmp=com.android.camera/.Camera (has extras) }
其中 extra 的 key 為 abc ,value 為字串 "hello"

還可以發(fā)送命令模擬手機(jī)低電環(huán)境:
實(shí)例:

adb shell am broadcast -a android.intent.action.BATTERY_CHANGED --ei "level" 3 --ei "scale" 100

ANDROID: 設(shè)置顯示窗口的SIZE和DENSITY

Android系統(tǒng)中有一個(gè)wm命令,可以設(shè)置顯示窗口的尺寸(重新設(shè)置屏幕的羅輯分辯率)和屏幕的dpi。

設(shè)置顯示窗口的尺寸

$ adb shell wm size 540x960

顯示窗口的尺寸可以比屏幕的物理分辨率大,也可以比它小。重置用如下命令:

$ adb shell wm size reset

設(shè)置完之后,你會(huì)發(fā)現(xiàn)SurfaceFlinger中的Layer的尺寸也發(fā)生的變化。
以Nexus4為例,原來Live Wallpaper: PhaseBeam Layer的尺寸為768×1280:

$ adb shell dumpsys SurfaceFlinger ... + Layer 0xb7bbf3b0 (com.android.phasebeam.PhaseBeamWallpaper)Region transparentRegion (this=0xb7bbf510, count=1)[ 0, 0, 0, 0]Region visibleRegion (this=0xb7bbf3b8, count=1)[ 0, 50, 768, 1184]layerStack= 0, z= 21000, pos=(0,0), size=( 768,1280), crop=( 0, 50, 768,1184), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000002, tr=[1.00, 0.00][0.00, 1.00]client=0xb7bad728format= 2, activeBuffer=[ 768x1280: 768, 3], queued-frames=0, mRefreshPending=0mTexName=10 mCurrentTexture=0mCurrentCrop=[0,0,0,0] mCurrentTransform=0mAbandoned=0-BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[768x1280], default-format=2, transform-hint=00, FIFO(0)={}>[00:0xb7bbef08] state=ACQUIRED, 0xb7b18260 [ 768x1280: 768, 3][01:0xb7baf328] state=FREE , 0xb7badaa8 [ 768x1280: 768, 3][02:0xb7b1a5d0] state=FREE , 0xb7bad9a0 [ 768x1280: 768, 3] ...

將顯示窗口的尺寸設(shè)為1080×1920之后:

$ adb shell dumpsys SurfaceFlinger ... + Layer 0xb7d596b8 (com.android.phasebeam.PhaseBeamWallpaper)Region transparentRegion (this=0xb7d59818, count=1)[ 0, 0, 0, 0]Region visibleRegion (this=0xb7d596c0, count=1)[ 0, 50, 1080, 1824]layerStack= 0, z= 21000, pos=(0,0), size=(1080,1920), crop=( 0, 50,1080,1824), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000002, tr=[1.00, 0.00][0.00, 1.00]client=0xb7dbf270format= 2, activeBuffer=[1080x1920:1152, 3], queued-frames=0, mRefreshPending=0mTexName=10 mCurrentTexture=2mCurrentCrop=[0,0,0,0] mCurrentTransform=0mAbandoned=0-BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[1080x1920], default-format=2, transform-hint=00, FIFO(0)={}[00:0xb7dd1fb0] state=FREE , 0xb7dd0048 [1080x1920:1152, 3][01:0xb7d5c2c8] state=FREE , 0xb7d39ca8 [1080x1920:1152, 3]>[02:0xb7d1d578] state=ACQUIRED, 0xb7d5cb18 [1080x1920:1152, 3] ...

可以想象得到,系統(tǒng)把這個(gè)layer對應(yīng)的窗口當(dāng)成了一個(gè)1080p屏幕來布局和繪制了。
設(shè)置屏幕的dpi

$ adb shell wm density 320

Android 將實(shí)際屏幕尺寸和密度的范圍 分為:

1.四種通用尺寸:小、正常、 大 和超大

2.六種通用的密度:

  • ldpi(低)~120dpi
  • mdpi(中)~160dpi
  • hdpi(高)~240dpi
  • xhdpi(超高)~320dpi
  • xxhdpi(超超高)~480dpi
  • xxxhdpi(超超超高)~640dpi

    ?

常用的dpi有160(mdpi), 240(hdpi), 320(xhdpi), 480(xxhdpi)。重置可用如下命令:

$ adb shell wm density reset

如何實(shí)現(xiàn) ,以設(shè)置顯示窗口尺寸為例(@android-5.1.1)
首先看一下wm命令如何通知WindowManagerService更新配置:
代碼:frameworks/base/cmds/wm/src/com/android/commands/wm/Wm.java

public class Wm extends BaseCommand {...public void onRun() throws Exception {mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(Context.WINDOW_SERVICE));if (mWm == null) {System.err.println(NO_SYSTEM_ERROR_CODE);throw new AndroidException("Can't connect to window manager; is the system running?");}String op = nextArgRequired();if (op.equals("size")) {runDisplaySize();} else if (op.equals("density")) {runDisplayDensity();} else if (op.equals("overscan")) {runDisplayOverscan();} else {showError("Error: unknown command '" + op + "'");return;}}...private void runDisplaySize() throws Exception {String size = nextArg();int w, h;if (size == null) {Point initialSize = new Point();Point baseSize = new Point();try {mWm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize);mWm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize);System.out.println("Physical size: " + initialSize.x + "x" + initialSize.y);if (!initialSize.equals(baseSize)) {System.out.println("Override size: " + baseSize.x + "x" + baseSize.y);}} catch (RemoteException e) {}return;} else if ("reset".equals(size)) {w = h = -1;} else {int div = size.indexOf('x');if (div <= 0 || div >= (size.length()-1)) {System.err.println("Error: bad size " + size);return;}String wstr = size.substring(0, div);String hstr = size.substring(div+1);try {w = Integer.parseInt(wstr);h = Integer.parseInt(hstr);} catch (NumberFormatException e) {System.err.println("Error: bad number " + e);return;}}try {if (w >= 0 && h >= 0) {// TODO(multidisplay): For now Configuration only applies to main screen.mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);} else {mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);}} catch (RemoteException e) {}}... }

先獲取WindowManagerService再調(diào)用它的setForcedDisplaySize()方法。
代碼:frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public class WindowManagerService extends IWindowManager.Stubimplements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {...@Overridepublic void setForcedDisplaySize(int displayId, int width, int height) {if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) !=PackageManager.PERMISSION_GRANTED) {throw new SecurityException("Must hold permission " +android.Manifest.permission.WRITE_SECURE_SETTINGS);}if (displayId != Display.DEFAULT_DISPLAY) {throw new IllegalArgumentException("Can only set the default display");}final long ident = Binder.clearCallingIdentity();try {synchronized(mWindowMap) {// Set some sort of reasonable bounds on the size of the display that we// will try to emulate.final int MIN_WIDTH = 200;final int MIN_HEIGHT = 200;final int MAX_SCALE = 2;final DisplayContent displayContent = getDisplayContentLocked(displayId);if (displayContent != null) {width = Math.min(Math.max(width, MIN_WIDTH),displayContent.mInitialDisplayWidth * MAX_SCALE);height = Math.min(Math.max(height, MIN_HEIGHT),displayContent.mInitialDisplayHeight * MAX_SCALE);setForcedDisplaySizeLocked(displayContent, width, height);Settings.Global.putString(mContext.getContentResolver(),Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);}}} finally {Binder.restoreCallingIdentity(ident);}}...// displayContent must not be nullprivate void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {Slog.i(TAG, "Using new display size: " + width + "x" + height);synchronized(displayContent.mDisplaySizeLock) {displayContent.mBaseDisplayWidth = width;displayContent.mBaseDisplayHeight = height;}reconfigureDisplayLocked(displayContent);}...// displayContent must not be nullprivate void reconfigureDisplayLocked(DisplayContent displayContent) {// TODO: Multidisplay: for now only use with default display.configureDisplayPolicyLocked(displayContent);displayContent.layoutNeeded = true;boolean configChanged = updateOrientationFromAppTokensLocked(false);mTempConfiguration.setToDefaults();mTempConfiguration.fontScale = mCurConfiguration.fontScale;if (computeScreenConfigurationLocked(mTempConfiguration)) {if (mCurConfiguration.diff(mTempConfiguration) != 0) {configChanged = true;}}if (configChanged) {mWaitingForConfig = true;startFreezingDisplayLocked(false, 0, 0);mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);}performLayoutAndPlaceSurfacesLocked();}...}setForcedDisplaySize()->setForcedDisplaySizeLocked()->reconfigureDisplayLocked()->SEND_NEW_CONFIGURATION

這里可以看到可以設(shè)置的屏幕窗口最小為(200,200),最大小顯示屏分辨率的兩倍。
而WindowManagerService又是如何通知DisplayManagerService更新配置:

WindowsManagerService$H.handleMessage(SEND_NEW_CONFIGURATION) ->WindowManagerService.sendNewConfiguration() ->ActivityManagerService.updateConfiguration() x2 ->WindowManagerService.setNewConfiguration() ->WindowManagerService.performLayoutAndPlaceSurfacesLocked() ->WindowManagerService.performLayoutAndPlaceSurfaceLockedLoop() ->WindowManagerService.performLayoutAndPlaceSurfaceLockedInner() ->DisplayManagerService$LocalService.performTraversalInTransactionFromWindowManager() ->DisplayManagerService.access$4200() ->DisplayManagerService.performTraversalInTransactionFromWindowManagerInternal() ->DisplayManagerService.performTraversalInTransactionLocked() ->DisplayManagerService.configureDisplayInTransactionLocked() ->LogicalDisplay.configureDisplayInTransactionLocked()

到這里就會(huì)去設(shè)置layer stack的尺寸和在屏幕上的位置:

final class LogicalDisplay {.../*** Applies the layer stack and transformation to the given display device* so that it shows the contents of this logical display.** We know that the given display device is only ever showing the contents of* a single logical display, so this method is expected to blow away all of its* transformation properties to make it happen regardless of what the* display device was previously showing.** The caller must have an open Surface transaction.** The display device may not be the primary display device, in the case* where the display is being mirrored.** @param device The display device to modify.* @param isBlanked True if the device is being blanked.*/public void configureDisplayInTransactionLocked(DisplayDevice device,boolean isBlanked) {final DisplayInfo displayInfo = getDisplayInfoLocked();final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();// Set the layer stack.device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);// Set the refresh ratedevice.requestRefreshRateLocked(mRequestedRefreshRate);// Set the viewport.// This is the area of the logical display that we intend to show on the// display device. For now, it is always the full size of the logical display.mTempLayerStackRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);// Set the orientation.// The orientation specifies how the physical coordinate system of the display// is rotated when the contents of the logical display are rendered.int orientation = Surface.ROTATION_0;if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {orientation = displayInfo.rotation;}// Apply the physical rotation of the display device itself.orientation = (orientation + displayDeviceInfo.rotation) % 4;// Set the frame.// The frame specifies the rotated physical coordinates into which the viewport// is mapped. We need to take care to preserve the aspect ratio of the viewport.// Currently we maximize the area to fill the display, but we could try to be// more clever and match resolutions.boolean rotated = (orientation == Surface.ROTATION_90|| orientation == Surface.ROTATION_270);int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;// Determine whether the width or height is more constrained to be scaled.// physWidth / displayInfo.logicalWidth => letter box// or physHeight / displayInfo.logicalHeight => pillar box//// We avoid a division (and possible floating point imprecision) here by// multiplying the fractions by the product of their denominators before// comparing them.int displayRectWidth, displayRectHeight;if (physWidth * displayInfo.logicalHeight< physHeight * displayInfo.logicalWidth) {// Letter box.displayRectWidth = physWidth;displayRectHeight = displayInfo.logicalHeight * physWidth / displayInfo.logicalWidth;} else {// Pillar box.displayRectWidth = displayInfo.logicalWidth * physHeight / displayInfo.logicalHeight;displayRectHeight = physHeight;}int displayRectTop = (physHeight - displayRectHeight) / 2;int displayRectLeft = (physWidth - displayRectWidth) / 2;mTempDisplayRect.set(displayRectLeft, displayRectTop,displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);device.setProjectionInTransactionLocked(orientation, mTempLayerStackRect, mTempDisplayRect);}... }

->DisplayDevice.setProjectionInTransactionLocked()
通知SurfaceFlinger:

abstract class DisplayDevice {.../*** Sets the display projection while in a transaction.** @param orientation defines the display's orientation* @param layerStackRect defines which area of the window manager coordinate* space will be used* @param displayRect defines where on the display will layerStackRect be* mapped to. displayRect is specified post-orientation, that is* it uses the orientation seen by the end-user*/public final void setProjectionInTransactionLocked(int orientation,Rect layerStackRect, Rect displayRect) {if (mCurrentOrientation != orientation|| mCurrentLayerStackRect == null|| !mCurrentLayerStackRect.equals(layerStackRect)|| mCurrentDisplayRect == null|| !mCurrentDisplayRect.equals(displayRect)) {mCurrentOrientation = orientation;if (mCurrentLayerStackRect == null) {mCurrentLayerStackRect = new Rect();}mCurrentLayerStackRect.set(layerStackRect);if (mCurrentDisplayRect == null) {mCurrentDisplayRect = new Rect();}mCurrentDisplayRect.set(displayRect);SurfaceControl.setDisplayProjection(mDisplayToken,orientation, layerStackRect, displayRect);}}... }

最后,SurfaceFlinger就會(huì)跟據(jù)這些信息對Layer進(jìn)行合成,顯示在屏幕上。
代碼:frameworks/native/services/surfaceflinger/DisplayDevice.cpp

void DisplayDevice::setProjection(int orientation,const Rect& newViewport, const Rect& newFrame) {Rect viewport(newViewport);Rect frame(newFrame);const int w = mDisplayWidth;const int h = mDisplayHeight;Transform R;DisplayDevice::orientationToTransfrom(orientation, w, h, &R);if (!frame.isValid()) {// the destination frame can be invalid if it has never been set,// in that case we assume the whole display frame.frame = Rect(w, h);}if (viewport.isEmpty()) {// viewport can be invalid if it has never been set, in that case// we assume the whole display size.// it's also invalid to have an empty viewport, so we handle that// case in the same way.viewport = Rect(w, h);if (R.getOrientation() & Transform::ROT_90) {// viewport is always specified in the logical orientation// of the display (ie: post-rotation).swap(viewport.right, viewport.bottom);}}dirtyRegion.set(getBounds());Transform TL, TP, S;float src_width = viewport.width();float src_height = viewport.height();float dst_width = frame.width();float dst_height = frame.height();if (src_width != dst_width || src_height != dst_height) {float sx = dst_width / src_width;float sy = dst_height / src_height;S.set(sx, 0, 0, sy);}float src_x = viewport.left;float src_y = viewport.top;float dst_x = frame.left;float dst_y = frame.top;TL.set(-src_x, -src_y);TP.set(dst_x, dst_y);// The viewport and frame are both in the logical orientation.// Apply the logical translation, scale to physical size, apply the // physical translation and finally rotate to the physical orientation.mGlobalTransform = R * TP * S * TL;const uint8_t type = mGlobalTransform.getType();mNeedsFiltering = (!mGlobalTransform.preserveRects() ||(type >= Transform::SCALE));mScissor = mGlobalTransform.transform(viewport);if (mScissor.isEmpty()) {mScissor = getBounds();}mOrientation = orientation;mViewport = viewport;mFrame = frame; }

aapt命令獲取apk詳細(xì)信息(包名、版本號、版本名稱、兼容api級別、啟動(dòng)Activity等)

  • 找到sdk的根目錄,然后找到build-tools文件夾,然后會(huì)看到一些build-tools的版本號,隨便點(diǎn)開一個(gè),就可以看到aapt

    ?

  • 獲取apk的詳細(xì)信息

    aapt dump badging app-debug.apk

    ?

    ?

  • ?



    作者:xmaihh
    鏈接:https://www.jianshu.com/p/5c2bf91b1ff8
    來源:簡書
    簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

    總結(jié)

    以上是生活随笔為你收集整理的adb命令实现一些有趣的功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。