經過 PackageManager 得到你想要的 App 信息

/top.png
/top.png

1、前言

開門見山,開篇明義。有些場景下,咱們會須要獲取一些其它 App 的各項信息,例如:App 名稱,包名、Icon 等。這個時候就須要使用到 PackageManager 這個類了。算法

本篇就 PackageManager 的使用,作一個詳盡的講解,助你拿到各項 App 的信息,固然也包括一些未安裝的 App 的信息。緩存

2、須要提早了解的一些類

當你須要獲取到指定 App 的各項信息的時候,你須要操做一些 Android 爲咱們提供的對應的 Api。app

你首先須要獲取 PackageManager(如下簡稱 PM) 對象,經過 PM 對象,你就能夠獲取到你須要的各項 App 的信息類。ide

這裏涉及到的 App 信息類包括:PackageInfo、ApplicationInfo、ActivityInfo/ServiceInfo/ProviderInfo 等,還有一個 ResolveInfo 類,它比較特殊一點,不和前面的結構爲從屬關係。學習

這些類,均可以在根據 AndroidManifest.xml 中定義的組件進行劃分,大概的結構以下。ui

/manifest.png
/manifest.png

能夠看到,它們之間的關係還它挺複雜的。線程

一個 PackageInfo 對應一個 ApplicationInfo,而其中又包含若干個 ActivityInfo、ServiceInfo、ProviderInfo。3d

2.1 PackageManager

PackageManager 是一個抽象類,咱們通常操做的 PackageManager ,其實是它的實現類 ApplicationPackageManager 這個對象。code

在 Context 中,就有獲取 PM 對象的方法,getPackageManager(),因此四大組件想要獲取它是很是簡單的。cdn

/getPackageManager.png
/getPackageManager.png

PM 中,提供了很是多的方法,供咱們經過不一樣的條件,獲取到 PackageInfo 對象、ApplicationInfo 對象等,它是本文的基礎。

2.2 PackageInfo

PackageInfo 從名稱上也能夠看出來,它主要用於存儲獲取到的 Package 的一些信息,包括:包名(packageName)、版本號(versionCode)、版本名(versionName)。

基本上拿到了 PackageInfo ,你就能夠拿到大部分此 Apk 相關的信息了。

而且,PackageInfo 中有一個 applicationInfo 的字段,是能夠直接獲取到與它相關的 ApplicationInfo 對象的。

這裏介紹幾個 PackageInfo 中,比較經常使用的字段:

  • packageName:包名。
  • versionCode:版本號
  • versionName:版本名。
  • firstInstallTime:首次安裝時間。
  • lastUpdateTime:最後一次覆蓋安裝時間。

2.3 ApplicationInfo

ApplicationInfo 相對於 PackageInfo 用的會比較少一些。它主要用於獲取 Apk 定義在 AndroidManifest.xml 中的一些信息。

這裏介紹幾個比價經常使用的:

  • packageName:包名
  • targetSdkVersion:目標 SDK 版本。
  • minSdkVersion:最小支持 SDK 版本,有 Api 限制,最低在 Api Level 24 及以上支持。
  • sourceDir:App 的 Apk 源文件存放的目錄。
  • dataDir:data 目錄的全路徑。
  • metaData:Manifest 中定義的 meta 標籤數據。
  • uid:當前 App 分配的 uid。

能夠看到 ApplicationInfo 涵蓋的信息,基本上都是在 AndroidManifest.xml 中定義的信息,而且有一些屬性是有 Api Level 限制的,因此不肯定的屬性,提早看一下文檔,肯定是否全版本支持。

2.4 ActivityInfo

ActivityInfo、ServiceInfo、ProviderInfo 這三個是平級的,熟悉的一眼就能看出來,它們就是 Android 定義的四大組件中的幾個。各自涵蓋了一部分信息。通常在外部獲取其餘 App 的信息的時候,不會獲取到這麼細緻的數據,若是有,看看這幾個類準沒錯。

那麼就再也不費時去介紹它們了。

3、基本操做

到如今基本上就已經瞭解到在當前設備上獲取到 Apk 信息的各項類了。

直接擺源碼說屬性有點枯燥。接下來咱們就帶着實際問題,來看看具體如何使用 PM。

3.1 獲取全部安裝的 App

若是想要獲取當前設備上已經安裝的全部 App,可使用 getInstalledPackages() 方法獲取到它全部的已安裝 App 的 PackageInfo 。

/getdeviceApp.png
/getdeviceApp.png

PackageManager 中,不少方法都會須要傳遞一個 flags 的字段,它表示你當前須要獲取到的 App 的信息。取值範圍有挺多的,獲取不一樣的信息使用不一樣的 Flags,一般若是沒有額外的要求,直接使用 GET_ACTIVITYS 便可。

3.2 判斷 App 是否安裝

這裏主要說的是經過包名,判斷 App 是否安裝在當前設備上。

最簡單的邏輯就是去獲取 PackageInfo ,若是能拿回來數據,就說明是有安裝的。

/isinstall.png
/isinstall.png

3.3 經過包名獲取PackageInfo

其實前面判斷 App 是否安裝的時候,就已經獲取到了 PackageInfo 信息,這裏只須要將它返回出去便可。

/getPakcageInfo.png
/getPakcageInfo.png

3.4 獲取版本號和版本名

這裏只須要根據 PackageInfo 中的字段,獲取到對應的值就行了。

/versionName.png
/versionName.png

3.5 獲取 App 的名稱

獲取 App 的名稱,就須要用到 ApplicationInfo 這個對象了,其中 loadLabel() 方法返回的,就是 App 的名稱。

/getAppLabel.png
/getAppLabel.png

3.6 獲取 App 的 Icon

在 ApplicationInfo 中,還能夠經過 loadIcon() 獲取到 App 的 Icon。它返回的是一個 Drawable 對象,能夠直接使用。

/getApplicationIcon.png
/getApplicationIcon.png

3.5 根據Apk 文件,獲取 PackageInfo

前面介紹的方法,都是基於一個已安裝的 App 的包名,來獲取額外的信息。

可是有時候,咱們只有一個未安裝的 Apk 文件,想要解析出 Apk 文件中的額外信息,PM 中,也有對應的 Api。很是的方便,直接使用 getPackageArchiveInfo() 便可。

/getarchiveinfo.png
/getarchiveinfo.png

只要拿到這個 Apk 文件相關的 PackageInfo 信息,就有辦法拿到其餘的名稱、icon 、版本號、版本名、包名等信息。和前面介紹的例子相似,這裏就再也不一一列舉了。

4、查缺補漏

總體來講,到這裏已經講解清楚如何使用 PM 獲取 App 的基本信息。

可是並不包含 App 在運行時的一些內存的狀況,哪些數據你想獲取,單單依靠 PackageManager 是作不到的,就再也不這裏展開說了,有機會再詳細說明一下。

還有就是,PM 中,不少方法,都是有可能觸發 『Package manager has died』這個 RuntimeException 的,其實就是不少個線程在頻繁調用。若是想要避免,加鎖加緩存便可。具體的狀況,能夠看看我以前的文章《PackageManager能夠亂用嗎?》。

今天在承香墨影公衆號的後臺,回覆『成長』。我會送你一些我整理的學習資料,包含:Android反編譯、算法。Web項目源碼。

推薦閱讀:

公衆號二維碼.jpg
公衆號二維碼.jpg

點贊或者分享吧~

相關文章
相關標籤/搜索