亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Android中識別預裝的第三方App

發布時間:2021-02-25 17:00:48 來源:億速云 閱讀:402 作者:Leah 欄目:移動開發

這期內容當中小編將會給大家帶來有關怎么在Android中識別預裝的第三方App,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

<package name="com.tencent.mm" 
codePath="/data/app/com.tencent.mm-TSn6yG4fF7A_EaxE5OtrHQ==" 
nativeLibraryPath="/data/app/com.tencent.mm-TSn6yG4fF7A_EaxE5OtrHQ==/lib" 
primaryCpuAbi="armeabi" publicFlags="945307204" 
privateFlags="0" ft="167702c7508" it="1676feab448" 
ut="167702c8a57" version="1360" userId="10118">
...
</package>

<package name="com.android.providers.downloads" 
codePath="/system/priv-app/DownloadProvider" 
nativeLibraryPath="/system/priv-app/DownloadProvider/lib" publicFlags="944258629" 
privateFlags="8" ft="11e8dc5d800" it="11e8dc5d800" 
ut="11e8dc5d800" version="28" sharedUserId="10006" isOrphaned="true">
...
</package>

其中it的值便是安裝時間,這里是用十六進制保存的,上面這2個App的安裝時間換算成十進制分別是1543770911816和1230739200000,對應的北京時間即2018-12-03 01:15:11和2009-01-01 00:00:00。 【嗯…想不到我12月3號1點多還沒睡,還安裝了個微信……】

系統啟動時,PackageManagerService由SystemServer啟動,PackageManagerService會掃描/data/app、/system/app、/system/priv-app、/vendor/app等等目錄,可以理解為會把這些目錄中的Apk安裝一遍,PackageManagerService會結合上面提到的packages.xml把各個App解析成PackageParser.Package對象。

思路

根據上面的知識,我們可以知道,如果packages.xml已經有了某個App的信息,那么這個App的安裝時間肯定就是packages.xml中記錄的時間。第一次啟動手機時packages.xml文件還不存在,或者新安裝一個App時,packages.xml中還沒有這個App的記錄,也就是說,確認這個packages.xml中的firstInstallTime(即it)是如果生成的便是問題的關鍵。

以下基于7.0.0_r1版本代碼。

通過搜索PackageManagerService,在scanPackageDirtyLI方法中有這么一段代碼:

// Take care of first install / last update times.
if (currentTime != 0) {
 if (pkgSetting.firstInstallTime == 0) {
 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
 pkgSetting.lastUpdateTime = currentTime;
 }
} else if (pkgSetting.firstInstallTime == 0) {
 // We need *something*. Take time time stamp of the file.
 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
} else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
 if (scanFileTime != pkgSetting.timeStamp) {
 // A package on the system image has changed; consider this
 // to be an update.
 pkgSetting.lastUpdateTime = scanFileTime;
 }
}

其中,currentTime是scanPackageDirtyLI方法的一個參數。pkgSetting是從packages.xml中讀取到的該App的信息(PackageSetting對象),如果packages.xml中不存在這個App的信息,會根據從Apk中解析到的信息創建一個PackageSetting。scanFileTime是Apk文件的最后修改時間。
可以看到存在這么幾種情況:

  • 傳入的currentTime不為0,從packages.xml中讀取到的firstInstallTime為0。這種情況會將firstInstallTime和lastUpdateTime均設置為傳入的currentTime的值。

  • 傳入的currentTime不為0,傳入的scanFlags設置了SCAN_UPDATE_TIME。這種情況會將lastUpdateTime設置為傳入的currentTime的值。

  • 傳入的currentTime為0,從packages.xml中讀取到的firstInstallTime為0。這種情況會將firstInstallTime和lastUpdateTime均設置為Apk的最后修改時間。

  • 傳入的currentTime為0,從packages.xml中讀取到的firstInstallTime不為0,傳入的policyFlags設置了PackageParser.PARSE_IS_SYSTEM_DIR,scanFileTime與packages.xml中讀取到的timeStamp(packages.xml中package標簽的ft)不相同。這種情況會將lastUpdateTime設置為Apk的最后修改時間。

對應到我們真實使用手機的場景,上面4種情況分別對應以下幾種場景:

  • 第一種情況:對應新安裝App。currentTime為當前的時間戳,會將這個新安裝的App的firstInstallTime和lastUpdateTime設置為當前時間戳。

  • 第二種情況:對應更新App。currentTime為當前的時間戳,會將lastUpdateTime設置為當前時間戳,firstInstallTime保持不變。

  • 第三種情況:手機啟動時PackageManagerService掃描各個目錄時發現了packages.xml中不存在的App(第一次啟動時所有App都不在packages.xml中)。

  • 第四種情況:系統更新等操作更新了系統分區的App,導致其文件的最后修改時間和記錄的不一致了,會被認為是更新。

我們可以大膽猜測,第一次啟動手機時會走第三種情況,因此系統App和預裝App的安裝時間是文件的最后修改時間,而這些文件的最后修改時間都是整秒的。

如何驗證?

我們先看看上面那個com.android.providers.downloads的Apk文件的最后修改時間。

# stat DownloadProvider.apk
 File: `DownloadProvider.apk'
 Size: 504712	 Blocks: 992	 IO Blocks: 512	regular file
Device: 10305h/66309d	 Inode: 1308	 Links: 1
Access: (644/-rw-r--r--)	Uid: ( 0/ root)	Gid: ( 0/ root)
Access: 2009-01-01 00:00:00.000000000
Modify: 2009-01-01 00:00:00.000000000
Change: 2009-01-01 00:00:00.000000000

時間與packages.xml中保存的時間一致,確實是把文件的最后修改時間作為了安裝時間。那么還有一個問題需要確認,傳入的currentTime是0嗎?

我們追溯調用鏈,會在PackageManagerService的構造函數中看到掃描各個目錄的方法。調用scanDirTracedLI方法傳入的最后一個參數0即scanPackageDirtyLI方法中的currentTime。感興趣的還可以仔細看看PackageManagerService到底掃描了哪些目錄。

File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
scanDirTracedLI(vendorOverlayDir, mDefParseFlags
  | PackageParser.PARSE_IS_SYSTEM
  | PackageParser.PARSE_IS_SYSTEM_DIR
  | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);

// Find base frameworks (resource packages without code).
scanDirTracedLI(frameworkDir, mDefParseFlags
  | PackageParser.PARSE_IS_SYSTEM
  | PackageParser.PARSE_IS_SYSTEM_DIR
  | PackageParser.PARSE_IS_PRIVILEGED,
  scanFlags | SCAN_NO_DEX, 0);

// Collected privileged system packages.
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
scanDirTracedLI(privilegedAppDir, mDefParseFlags
  | PackageParser.PARSE_IS_SYSTEM
  | PackageParser.PARSE_IS_SYSTEM_DIR
  | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);

// Collect ordinary system packages.
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
scanDirTracedLI(systemAppDir, mDefParseFlags
  | PackageParser.PARSE_IS_SYSTEM
  | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

// Collect all vendor packages.
File vendorAppDir = new File("/vendor/app");
try {
 vendorAppDir = vendorAppDir.getCanonicalFile();
} catch (IOException e) {
 // failed to look up canonical path, continue with original one
}
scanDirTracedLI(vendorAppDir, mDefParseFlags
  | PackageParser.PARSE_IS_SYSTEM
  | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

// Collect all OEM packages.
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
scanDirTracedLI(oemAppDir, mDefParseFlags
  | PackageParser.PARSE_IS_SYSTEM
  | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

...

scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);

scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
  | PackageParser.PARSE_FORWARD_LOCK,
  scanFlags | SCAN_REQUIRE_KNOWN, 0);

如果感興趣,你可以去跟一下安裝App和更新App的代碼,看傳入的currentTime是不是當前的時間戳。

到此,我們已經證明了第一次啟動手機時,系統會把文件的最后修改時間當成系統App和預裝App的安裝時間,而這個時間一般是類似于上面那樣2009-01-01 00:00:00.000000000的整秒的時間(至于為什么是這樣,那就是另一個問題了),而我們自己安裝App時幾乎不可能在一個整秒的時間安裝,所有我們可以用安裝時間是否為整秒來區分手機預裝的App和用戶手動安裝的App

上述就是小編為大家分享的怎么在Android中識別預裝的第三方App了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

涞源县| 通州市| 垫江县| 古田县| 钦州市| 商河县| 太湖县| 开原市| 乐东| 铜梁县| 营山县| 鹤壁市| 乾安县| 灵武市| 石门县| 精河县| 佳木斯市| 南开区| 许昌市| 玉田县| 山东省| 巧家县| 孟连| 虎林市| 雷山县| 甘孜| 佛教| 新郑市| 甘谷县| 锡林郭勒盟| 铜川市| 策勒县| 安福县| 奈曼旗| 专栏| 嫩江县| 拜城县| 岚皋县| 吴川市| 湛江市| 白山市|