APK安裝流程詳解2——PackageManager簡介

APK安裝流程系列文章整體內(nèi)容如下:

本片文章主要內(nèi)容如下:

  • 1写半、PackageManager介紹
  • 2、PackageManager類概述
  • 3玷或、PackageManager與APK安裝
  • 4腕柜、PackageManager的功能
  • 5喊熟、PackageManager常用方法
  • 6愿待、PackageManager中關于"安裝"的幾個方法

俗話說的好硝皂,得中原者盯另,得天下谢床,那么想要了解Android的安裝了流程就不得不提及一個重要的類"PackageManager"我們就先來了解這兩個類

一兄一、PackageManager介紹

PackageManager源碼地址

Android系統(tǒng)為我們提供了很多服務的管理類,比如ActivityManager识腿、PowrManager出革,那么和安裝APK有關就是PackageManager了,它負責管理應用程序包覆履,通過它就可以獲取應用程序信息蹋盆。

二、PackageManager類概述

這個類已經(jīng)5000多行硝全,我們就不詳細介紹了栖雾,我們來看下這個類

/**
 * Class for retrieving various kinds of information related to the application
 * packages that are currently installed on the device.
 *
 * You can find this class through {@link Context#getPackageManager}.
 */
public abstract class PackageManager {
   ...
}

通過上面代碼我們知道這個類是抽象類,那我們來看下注釋

PackageManager這個類是檢測當前已經(jīng)安裝在當前設備上的應用程序包的信息伟众。你可以調(diào)用Context類的getPackageManager()方法來獲取PackageManager方法析藕。

三、PackageManager與APK安裝

PackageManager是一個實際上管理應用程序安裝凳厢、卸載和升級的API账胧。當我們安裝APK文件時竞慢,PackageManager會解析APK包文件和顯示確認信息。當我們點擊OK按鈕后治泥,PackageManager會調(diào)用一個叫"InstallPackage"的方法筹煮,這個方法有4個參數(shù),也就是uri居夹、installFlags败潦、observer、installPackagename准脂。PackageManager會啟動一個叫"package"的servcie服務劫扒,現(xiàn)在所有模糊的東西會發(fā)生在這個service中。

APK安裝流程.png

四狸膏、PackageManager的功能

  • 1沟饥、安裝、卸載應用
  • 2湾戳、查詢permission相關信息
  • 3贤旷、查詢Application相關信息(application、activity砾脑、receiver遮晚、service、provider及相應屬性等)
  • 4拦止、查詢已安裝應用
  • 5、增加糜颠、刪除permission
  • 6汹族、清除用戶數(shù)據(jù)、緩存其兴、代碼等

五顶瞒、PackageManager常用方法

1、public abstract PackageInfo getPackageInfo(String packageName, int flags)方法:

通過包名獲取該包名對應的應用程序的PackageInfo對象

代碼在PackageManager.java2031行

    /**
     * Retrieve overall information about an application package that is
     * installed on the system.
     * <p>
     * Throws {@link NameNotFoundException} if a package with the given name can
     * not be found on the system.
     *
     * @param packageName The full name (i.e. com.google.apps.contacts) of the
     *            desired package.
     * @param flags Additional option flags. Use any combination of
     *            {@link #GET_ACTIVITIES}, {@link #GET_GIDS},
     *            {@link #GET_CONFIGURATIONS}, {@link #GET_INSTRUMENTATION},
     *            {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
     *            {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
     *            {@link #GET_SIGNATURES}, {@link #GET_UNINSTALLED_PACKAGES} to
     *            modify the data returned.
     * @return Returns a PackageInfo object containing information about the
     *         package. If flag GET_UNINSTALLED_PACKAGES is set and if the
     *         package is not found in the list of installed applications, the
     *         package information is retrieved from the list of uninstalled
     *         applications (which includes installed applications as well as
     *         applications with data directory i.e. applications which had been
     *         deleted with {@code DONT_DELETE_DATA} flag set).
     * @see #GET_ACTIVITIES
     * @see #GET_GIDS
     * @see #GET_CONFIGURATIONS
     * @see #GET_INSTRUMENTATION
     * @see #GET_PERMISSIONS
     * @see #GET_PROVIDERS
     * @see #GET_RECEIVERS
     * @see #GET_SERVICES
     * @see #GET_SIGNATURES
     * @see #GET_UNINSTALLED_PACKAGES
     */
    public abstract PackageInfo getPackageInfo(String packageName, int flags)
            throws NameNotFoundException;

先翻譯一下注釋:

檢索出有關系統(tǒng)上安裝應用程序包的總體信息

關于PackageInfo這各類請參考APK安裝流程詳解1——有關"安裝ing"的實體類概述
元旬。它表示檢索有關系統(tǒng)上安裝的應用程序包的總體信息榴徐。

2、public abstract String[] currentToCanonicalPackageNames(String[] names)方法:

代碼在PackageManager.java2041行

    /**
     * Map from the current package names in use on the device to whatever
     * the current canonical name of that package is.
     * @param names Array of current names to be mapped.
     * @return Returns an array of the same size as the original, containing
     * the canonical name for each package.
     */
    public abstract String[] currentToCanonicalPackageNames(String[] names);

簡單翻譯注釋如下:

從設備上使用當前包名映射到該軟件包名的當前規(guī)范名稱匀归。

  • 入?yún)arams names 表示要映射的當前名稱的數(shù)組
  • 出參return 表示與原始數(shù)組大小相同的數(shù)組坑资,其中包含每個包的規(guī)范名稱

如果修改包名會用到,沒有修改過包名一般不會用到

3穆端、public abstract String[] canonicalToCurrentPackageNames(String[] names)方法:

主要是相對于上面的方法

代碼在PackageManager.java2049行

    /**
     * Map from a packages canonical name to the current name in use on the device.
     * @param names Array of new names to be mapped.
     * @return Returns an array of the same size as the original, containing
     * the current name for each package.
     */
    public abstract String[] canonicalToCurrentPackageNames(String[] names);

簡單翻譯注釋如下:

將軟件包規(guī)范名稱映射到設備上正在使用的當前名稱袱贮。

  • 入?yún)arams names 表示要映射的新名稱數(shù)組
  • 出參return 表示返回與原始數(shù)組大小相同的數(shù)組,其中包含每個包的當前名稱体啰。

其中canonicalToCurrentPackageNames()和currentToCanonicalPackageNames()方法是相反的兩個方法

4攒巍、public abstract Intent getLaunchIntentForPackage(String packageName)方法:

獲取一個應用程序的Lauch的Intent

代碼在PackageManager.java 2066行

    /**
     * Returns a "good" intent to launch a front-door activity in a package.
     * This is used, for example, to implement an "open" button when browsing
     * through packages.  The current implementation looks first for a main
     * activity in the category {@link Intent#CATEGORY_INFO}, and next for a
     * main activity in the category {@link Intent#CATEGORY_LAUNCHER}. Returns
     * <code>null</code> if neither are found.
     *
     * @param packageName The name of the package to inspect.
     *
     * @return A fully-qualified {@link Intent} that can be used to launch the
     * main activity in the package. Returns <code>null</code> if the package
     * does not contain such an activity, or if <em>packageName</em> is not
     * recognized.
     */
    public abstract Intent getLaunchIntentForPackage(String packageName);

返回一個"包"中的"入口"Activity的Intent嗽仪,例如,這是類似于在瀏覽包的"打開"按鈕柒莉。這個當前的安裝啟動第一步在category(CATEGORY_INFO)中尋找main Activity闻坚,然后在category(CATEGORY_LAUNCHER)尋找main Activity。如果找不到就返回null兢孝。

入?yún)⑹前?/p>

5窿凤、public abstract Intent getLeanbackLaunchIntentForPackage(String packageName)方法:

獲取一個TV應用的Leanback的Intent

代碼在PackageManager.java2083行

    /**
     * Return a "good" intent to launch a front-door Leanback activity in a
     * package, for use for example to implement an "open" button when browsing
     * through packages. The current implementation will look for a main
     * activity in the category {@link      * return null if no main leanback activities are found.
     * <p>
     * Throws {@link NameNotFoundException} if a package with the given name
     * cannot be found on the system.
     *
     * @param packageName The name of the package to inspect.
     * @return Returns either a fully-qualified Intent that can be used to launch
     *         the main Leanback activity in the package, or null if the package
     *         does not contain such an activity.
     */
    public abstract Intent getLeanbackLaunchIntentForPackage(String packageName);

Leanback activity一般在TV上使用的比較多,上面這個方法返回的Intent的一般在AndroidManifest如下:

  <activity
    android:name="com.example.android.TvActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.Leanback">
    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
    </intent-filter>
  </activity>

其實就是返回的是com.example.android.TvActivity的打開Intent

翻譯注釋如下:

返回一個"合適的"Intent西潘,這個Intent是打開LeanbackActivity的入口Intent卷玉。例如,類似于在瀏覽包的"打開"按鈕喷市。這個將找匹配CATEGORY_LEANBACK_LAUNCHER的Activity相种。如果沒有找到則返回null。

6品姓、public abstract int[] getPackageGids(String packageName)方法:

獲取相應包的Group ids

代碼在PackageManager.java2097行

    /**
     * Return an array of all of the POSIX secondary group IDs that have been
     * assigned to the given package.
     * <p>
     * Note that the same package may have different GIDs under different
     * {@link UserHandle} on the same device.
     *
     * @param packageName The full name (i.e. com.google.apps.contacts) of the
     *            desired package.
     * @return Returns an int array of the assigned GIDs, or null if there are
     *         none.
     * @throws NameNotFoundException if a package with the given name cannot be
     *             found on the system.
     */
    public abstract int[] getPackageGids(String packageName)
            throws NameNotFoundException;

翻譯注釋如下:

  • 返回已分配給包的所有的POSIX輔助組ID的數(shù)組
  • 請注意寝并,相同的包可能會有不同的GID, 因為可能存在在同一個設備開啟了不同的"用戶模式“下
  • 入?yún)arams packageName 是全包名
  • 出參 表示 返回應用程序對應的GID的int 數(shù)組腹备,如果沒有應用程序衬潦,則返回null。

7植酥、public abstract int[] getPackageUid(String packageName)方法:

獲取相應包的UID
代碼在PackageManager.java2113行

    /**
     * Return the UID associated with the given package name.
     * <p>
     * Note that the same package will have different UIDs under different
     * {@link UserHandle} on the same device.
     *
     * @param packageName The full name (i.e. com.google.apps.contacts) of the
     *            desired package.
     * @return Returns an integer UID who owns the given package name.
     * @throws NameNotFoundException if a package with the given name can not be
     *             found on the system.
     */
    public abstract int getPackageUid(String packageName, @PackageInfoFlags int flags)
            throws NameNotFoundException;

翻譯注釋如下:

  • 返回與給定包名的對應的UID
  • 請注意镀岛,相同的包可能會有不同的UID, 因為可能存在在同一個設備開啟了不同的"用戶模式“下
  • 入?yún)arams packageName 是全包名
  • 出參 表示 返回給定包名的int 型的UID

8友驮、 public abstract PermissionInfo getPermissionInfo(String name, int flags)方法:

根據(jù)包名和指定的flags獲取指定的授權信息

代碼在PackageManager.java2130行

    /**
     * Retrieve all of the information we know about a particular permission.
     *
     * @param name The fully qualified name (i.e. com.google.permission.LOGIN)
     *         of the permission you are interested in.
     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
     *         retrieve any meta-data associated with the permission.
     *
     * @return Returns a {@link PermissionInfo} containing information about the
     *         permission.
     * @throws NameNotFoundException if a package with the given name cannot be
     *             found on the system.
     *
     * @see #GET_META_DATA
     */
    public abstract PermissionInfo getPermissionInfo(String name,  int flags)
throws NameNotFoundException;

翻譯注釋如下:

  • 檢測出我們想要知道所有關于權限信息
  • 入?yún)arams name 是權限的全名稱漂羊,比如:com.google.permission.LOGIN
  • 入?yún)arams name 附加選項的標志位,用來獲取檢索出與權限相關聯(lián)的元數(shù)據(jù)(通過使用"GET_META_DATA")
  • 出參 表示 返回權限信息的對象卸留,里面包含我們關于權限信息的的所有信息走越。

10、 public abstract List<PermissionInfo> queryPermissionsByGroup(String group,int flags)方法:

獲取所有的PermissionInfo集合

代碼在PackageManager.java2148行

    /**
     * Query for all of the permissions associated with a particular group.
     *
     * @param group The fully qualified name (i.e. com.google.permission.LOGIN)
     *         of the permission group you are interested in.  Use null to
     *         find all of the permissions not associated with a group.
     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
     *         retrieve any meta-data associated with the permissions.
     *
     * @return Returns a list of {@link PermissionInfo} containing information
     *             about all of the permissions in the given group.
     * @throws NameNotFoundException if a package with the given name cannot be
     *             found on the system.
     *
     * @see #GET_META_DATA
     */
    public abstract List<PermissionInfo> queryPermissionsByGroup(String group,int flags) throws NameNotFoundException;

翻譯注釋如下:

  • 查詢與特定組相關的所有權限
  • 入?yún)arams group 需要查詢組的全名稱耻瑟,例如:com.google.permission.LOGIN旨指,如果使用NULL則可以查詢與組無關的所有權限
  • 入?yún)arams name 附加選項的標志位,用來獲取檢索出與權限相關聯(lián)的的元數(shù)據(jù)(通過使用"GET_META_DATA")
  • 出參 表示 返回權限信息的對象的集合

10喳整、 public abstract List<PermissionInfo> queryPermissionsByGroup(String group,int flags)方法:

根據(jù)指定Group明和獲取PermissionGroupInfo對象谆构。
代碼在PackageManager.java2166行

   /**
     * Retrieve all of the information we know about a particular group of
     * permissions.
     *
     * @param name The fully qualified name (i.e. com.google.permission_group.APPS)
     *         of the permission you are interested in.
     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
     *         retrieve any meta-data associated with the permission group.
     *
     * @return Returns a {@link PermissionGroupInfo} containing information
     *         about the permission.
     * @throws NameNotFoundException if a package with the given name cannot be
     *             found on the system.
     *
     * @see #GET_META_DATA
     */
    public abstract PermissionGroupInfo getPermissionGroupInfo(String name,int flags) throws NameNotFoundException;

翻譯注釋如下:

  • 檢索出我們知道的關于一組特殊權限的所有信息
  • 入?yún)arams name 一組權限的全限定名稱,例如com.google.permission_group.APPS
  • 入?yún)arams flags 附加選項的標志位算柳,用來獲取檢索出與權限相關聯(lián)的的元數(shù)據(jù)(通過使用"GET_META_DATA")
  • 出參 表示 返回一個包含權限組信息的PermissionGroupInfo對象

11低淡、public abstract List<PermissionGroupInfo> getAllPermissionGroups( int flags)方法:

獲取所有的PermissGroup集合

代碼在PackageManager.java2178行

    /**
     * Retrieve all of the known permission groups in the system.
     *
     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
     *         retrieve any meta-data associated with the permission group.
     *
     * @return Returns a list of {@link PermissionGroupInfo} containing
     *         information about all of the known permission groups.
     *
     * @see #GET_META_DATA
     */
    public abstract List<PermissionGroupInfo> getAllPermissionGroups(
            @PermissionGroupInfoFlags int flags);

翻譯注釋如下:

  • 檢索出系統(tǒng)中所有已知的權限
  • 入?yún)arams flags 附加選項的標志位,用來獲取檢索出與權限相關聯(lián)的的元數(shù)據(jù)(通過使用"GET_META_DATA")
  • 出參 表示 返回有關所有權限的組的信息

12、public abstract ApplicationInfo getApplicationInfo(String packageName,int flags) throws NameNotFoundException;方法:

根據(jù)包名返回其對應的ApplicationInfo信息

代碼在PackageManager.java2207行

    /**
     * Retrieve all of the information we know about a particular
     * package/application.
     *
     * @param packageName The full name (i.e. com.google.apps.contacts) of an
     *         application.
     * @param flags Additional option flags. Use any combination of
     *         {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
     *         {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES}
     *         to modify the data returned.
     *
     * @return An {@link ApplicationInfo} containing information about the
     *         package. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the
     *         package is not found in the list of installed applications, the
     *         application information is retrieved from the list of uninstalled
     *         applications (which includes installed applications as well as
     *         applications with data directory i.e. applications which had been
     *         deleted with {@code DONT_DELETE_DATA} flag set).
     * @throws NameNotFoundException if a package with the given name cannot be
     *             found on the system.
     *
     * @see #GET_META_DATA
     * @see #GET_SHARED_LIBRARY_FILES
     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
     * @see #MATCH_SYSTEM_ONLY
     * @see #MATCH_UNINSTALLED_PACKAGES
     */
    public abstract ApplicationInfo getApplicationInfo(String packageName,
            int flags) throws NameNotFoundException;

翻譯注釋如下:

  • 檢索出一個應用程序的所有信息(ApplicationInfo)
  • 入?yún)arams packageName 包全名例如com.google.apps.contacts
  • 入?yún)arams flags 附加選項的標志位蔗蹋,可以使用下面這四個的任何組合過濾返回值
    • GET_META_DATA :ComponentInfo的標志位何荚,返回與該組件(ComponentInfo)相關聯(lián)的(metaData)數(shù)據(jù)(android.os.Bundle)。
    • GET_SHARED_LIBRARY_FILES:ApplicationInfo的標志位猪杭,返回與應用程序關聯(lián)的共享庫(ApplicationInfo路徑)
    • MATCH_DISABLED_UNTIL_USED_COMPONENTS:PackageInfo的標志位餐塘,表示包含禁用的組件。如果已處于禁用狀態(tài)程序將變更為啟用皂吮。
    • MATCH_SYSTEM_ONLYL:查詢標志戒傻,僅包含有系統(tǒng)的應用程序組件
    • MATCH_UNINSTALLED_PACKAGES:參數(shù)標志位,表示檢索出所有有數(shù)據(jù)的目錄的應用程序(主要是卸載的)的信息
  • 出參 表示 返回一個ApplicationInfo蜂筹,里面有關包的所有信息需纳。

13、public abstract ApplicationInfo getApplicationInfo(String packageName,int flags) throws NameNotFoundException;方法:

根據(jù)組件和要求返回特定的ActivityInfo

代碼在PackageManager.java2230行

    /**
     * Retrieve all of the information we know about a particular activity
     * class.
     *
     * @param component The full component name (i.e.
     *            com.google.apps.contacts/com.google.apps.contacts.
     *            ContactsList) of an Activity class.
     * @param flags Additional option flags. Use any combination of
     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},{@GET_INTENT_FILTERS}
     *           
     *            returned.
     * @return An {@link ActivityInfo} containing information about the
     *         activity.
     * @throws NameNotFoundException if a package with the given name cannot be
     *             found on the system.
     */
    public abstract ActivityInfo getActivityInfo(ComponentName component,int flags) throws NameNotFoundException;

翻譯注釋如下:

  • 檢索出一個特定的Activity類的所有信息
  • 入?yún)arams component 組件的全名稱例如:com.google.apps.contacts/com.google.apps.contacts. ContactsList中的一個Activity類
  • 入?yún)arams flags 附加選項的標志位艺挪,你可以理解為篩選條件不翩,可以使用的標志位為:
    • GET_META_DATA :ComponentInfo的標志位,返回與該組件(ComponentInfo)相關聯(lián)的(metaData)數(shù)據(jù)(android.os.Bundle)麻裳。
    • GET_SHARED_LIBRARY_FILES:ApplicationInfo的標志位口蝠,返回與應用程序關聯(lián)的共享庫(ApplicationInfo路徑)
    • GET_INTENT_FILTERS:包的標志位,返回支持IntentFilter的相關組件津坑。
  • 出參 表示 返回一個ActivityInfo妙蔗,里面包含類的所有信息。

14疆瑰、public abstract ActivityInfo getReceiverInfo(ComponentName component, int flags)方法:

根據(jù)組件和要求返回特定的ActivityInfo

代碼在PackageManager.java2253行

    /**
     * Retrieve all of the information we know about a particular receiver
     * class.
     *
     * <p>Throws {@link NameNotFoundException} if a receiver with the given
     * class name cannot be found on the system.
     *
     * @param component The full component name (i.e.
     * com.google.apps.calendar/com.google.apps.calendar.CalendarAlarm) of a Receiver
     * class.
     * @param flags Additional option flags.  Use any combination of
     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
     * to modify the data returned.
     *
     * @return {@link ActivityInfo} containing information about the receiver.
     *
     * @see #GET_INTENT_FILTERS
     * @see #GET_META_DATA
     * @see #GET_SHARED_LIBRARY_FILES
     */
    public abstract ActivityInfo getReceiverInfo(ComponentName component,
            int flags) throws NameNotFoundException;

翻譯注釋如下:

  • 檢索出一個特定的Receiver類的所有信息(這里主要指ActivityInfo)
  • 入?yún)arams component 組件的全名稱例如:com.google.apps.calendar/com.google.apps.calendar.CalendarAlarm中的一個Receiver類
  • 入?yún)arams flags 附加選項的標志位眉反,你可以理解為篩選條件,可以使用的標志位為:
    • GET_META_DATA :ComponentInfo的標志位穆役,返回與該組件(ComponentInfo)相關聯(lián)的(metaData)數(shù)據(jù)(android.os.Bundle)禁漓。
    • GET_SHARED_LIBRARY_FILES:ApplicationInfo的標志位,返回與應用程序關聯(lián)的共享庫(ApplicationInfo路徑)
  • 出參 表示 返回一個ActivityInfo孵睬,里面包含Receiver類的所有信息。

15伶跷、public abstract ServiceInfo getServiceInfo(ComponentName component, int flags))方法:

根據(jù)組件和要求返回特定的ServiceInfo

代碼在PackageManager.java2275行

    /**
     * Retrieve all of the information we know about a particular service
     * class.
     *
     * <p>Throws {@link NameNotFoundException} if a service with the given
     * class name cannot be found on the system.
     *
     * @param component The full component name (i.e.
     * com.google.apps.media/com.google.apps.media.BackgroundPlayback) of a Service
     * class.
     * @param flags Additional option flags.  Use any combination of
     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
     * to modify the data returned.
     *
     * @return ServiceInfo containing information about the service.
     *
     * @see #GET_META_DATA
     * @see #GET_SHARED_LIBRARY_FILES
     */
    public abstract ServiceInfo getServiceInfo(ComponentName component,
            int flags) throws NameNotFoundException;

翻譯注釋如下:

  • 檢索出一個特定的Service類的所有信息(這里主要指ServiceInfo)
  • 入?yún)arams component 組件的全名稱例如:com.google.apps.media/com.google.apps.media.BackgroundPlayback中的一個Service類
  • 入?yún)arams flags 附加選項的標志位掰读,你可以理解為篩選條件,可以使用的標志位為:
    • GET_META_DATA :ComponentInfo的標志位叭莫,返回與該組件(ComponentInfo)相關聯(lián)的(metaData)數(shù)據(jù)(android.os.Bundle)蹈集。
    • GET_SHARED_LIBRARY_FILES:ApplicationInfo的標志位,返回與應用程序關聯(lián)的共享庫(ApplicationInfo路徑)
  • 出參 表示 返回一個ServiceInfo雇初,里面包含Service類的所有信息拢肆。

16、public abstract ProviderInfo getProviderInfo(ComponentName component, int flags) 方法:

根據(jù)組件和要求返回特定的ProviderInfo

代碼在PackageManager.java2297行

    /**
     * Retrieve all of the information we know about a particular content
     * provider class.
     *
     * <p>Throws {@link NameNotFoundException} if a provider with the given
     * class name cannot be found on the system.
     *
     * @param component The full component name (i.e.
     * com.google.providers.media/com.google.providers.media.MediaProvider) of a
     * ContentProvider class.
     * @param flags Additional option flags.  Use any combination of
     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
     * to modify the data returned.
     *
     * @return ProviderInfo containing information about the service.
     *
     * @see #GET_META_DATA
     * @see #GET_SHARED_LIBRARY_FILES
     */
    public abstract ProviderInfo getProviderInfo(ComponentName component,
            int flags) throws NameNotFoundException;

翻譯注釋如下:

  • 檢索出一個特定的content provider類的所有信息(這里主要指ProviderInfo)
  • 入?yún)arams component 組件的全名稱例如:com.google.providers.media/com.google.providers.media.MediaProvider中的一個ContentProvider類
  • 入?yún)arams flags 附加選項的標志位,你可以理解為篩選條件郭怪,可以使用的標志位為:
    • GET_META_DATA :ComponentInfo的標志位支示,返回與該組件(ComponentInfo)相關聯(lián)的(metaData)數(shù)據(jù)(android.os.Bundle)。
    • GET_SHARED_LIBRARY_FILES:ApplicationInfo的標志位鄙才,返回與應用程序關聯(lián)的共享庫(ApplicationInfo路徑)
  • 出參 表示 返回一個ProviderInfo颂鸿。

17、public abstract ProviderInfo getProviderInfo(ComponentName component, int flags) 方法:

獲取設備上安裝的所有軟件包

代碼在PackageManager.java2334行

    /**
     * Return a List of all packages that are installed
     * on the device.
     *
     * @param flags Additional option flags. Use any combination of
     * {@link #GET_ACTIVITIES},
     * {@link #GET_GIDS},
     * {@link #GET_CONFIGURATIONS},
     * {@link #GET_INSTRUMENTATION},
     * {@link #GET_PERMISSIONS},
     * {@link #GET_PROVIDERS},
     * {@link #GET_RECEIVERS},
     * {@link #GET_SERVICES},
     * {@link #GET_SIGNATURES},
     * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
     *
     * @return A List of PackageInfo objects, one for each package that is
     *         installed on the device.  In the unlikely case of there being no
     *         installed packages, an empty list is returned.
     *         If flag GET_UNINSTALLED_PACKAGES is set, a list of all
     *         applications including those deleted with {@code DONT_DELETE_DATA}
     *         (partially installed apps with data directory) will be returned.
     *
     * @see #GET_ACTIVITIES
     * @see #GET_GIDS
     * @see #GET_CONFIGURATIONS
     * @see #GET_INSTRUMENTATION
     * @see #GET_PERMISSIONS
     * @see #GET_PROVIDERS
     * @see #GET_RECEIVERS
     * @see #GET_SERVICES
     * @see #GET_SIGNATURES
     * @see #GET_UNINSTALLED_PACKAGES
     */
    public abstract List<PackageInfo> getInstalledPackages(int flags);

翻譯注釋如下:

  • 返回設備上所有已經(jīng)安裝的應用程序集合
  • 入?yún)arams flags 附加選項的標志位攒庵,你可以理解為篩選條件嘴纺,可以使用的標志位為:
    • GET_ACTIVITIES :(packageInfo的標志)表示 返回包(packageInfo)中包含的所有Activity信息
    • GET_GIDS :(packageInfo的標志)表示 返回關聯(lián)的GID(groupId)
    • GET_CONFIGURATIONS :(packageInfo的標志)表示 配置選項信息
    • GET_INSTRUMENTATION :(PackageInfo的標志)表示 是否使用了instrumentation
    • GET_PERMISSIONS :(PackageInfo的標志)表示 是否使用了permissions
    • GET_PROVIDERS :(PackageInfo的標志)表示 是否使用了providers
    • GET_RECEIVERS :(PackageInfo的標志)表示 是否使用了recevier
    • GET_SERVICES :(PackageInfo的標志)表示 是否使用了service
    • GET_SIGNATURES :(PackageInf的標志) 表示是否使用包的簽名信息
    • GET_UNINSTALLED_PACKAGES:參數(shù)標志位,表示檢索出所有有數(shù)據(jù)的目錄的應用程序(主要是卸載的)的信息
  • 出參 表示 PackageInfo的List集合

18浓冒、public abstract List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags)方法:

獲取具有特定權限的PackageInfo

代碼在PackageManager.java2366行

    /**
     * Return a List of all installed packages that are currently
     * holding any of the given permissions.
     *
     * @param flags Additional option flags. Use any combination of
     * {@link #GET_ACTIVITIES},
     * {@link #GET_GIDS},
     * {@link #GET_CONFIGURATIONS},
     * {@link #GET_INSTRUMENTATION},
     * {@link #GET_PERMISSIONS},
     * {@link #GET_PROVIDERS},
     * {@link #GET_RECEIVERS},
     * {@link #GET_SERVICES},
     * {@link #GET_SIGNATURES},
     * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
     *
     * @return Returns a List of PackageInfo objects, one for each installed
     * application that is holding any of the permissions that were provided.
     *
     * @see #GET_ACTIVITIES
     * @see #GET_GIDS
     * @see #GET_CONFIGURATIONS
     * @see #GET_INSTRUMENTATION
     * @see #GET_PERMISSIONS
     * @see #GET_PROVIDERS
     * @see #GET_RECEIVERS
     * @see #GET_SERVICES
     * @see #GET_SIGNATURES
     * @see #GET_UNINSTALLED_PACKAGES
     */
    public abstract List<PackageInfo> getPackagesHoldingPermissions(
            String[] permissions, int flags);

翻譯注釋如下:

  • 返回當前設備上所有已安裝應用程序中的具有一些特殊權限的安裝包集合
  • 入?yún)arams flags 附加選項的標志位栽渴,你可以理解為篩選條件,可以使用的標志位為:
    • GET_ACTIVITIES :(packageInfo的標志)表示 返回包(packageInfo)中包含的所有Activity信息
    • GET_GIDS :(packageInfo的標志)表示 返回關聯(lián)的GID(groupId)
    • GET_CONFIGURATIONS :(packageInfo的標志)表示 配置選項信息
    • GET_INSTRUMENTATION :(PackageInfo的標志)表示 是否使用了instrumentation
    • GET_PERMISSIONS :(PackageInfo的標志)表示 是否使用了permissions
    • GET_PROVIDERS :(PackageInfo的標志)表示 是否使用了providers
    • GET_RECEIVERS :(PackageInfo的標志)表示 是否使用了recevier
    • GET_SERVICES :(PackageInfo的標志)表示 是否使用了service
    • GET_SIGNATURES :(PackageInf的標志) 表示是否使用包的簽名信息
    • GET_UNINSTALLED_PACKAGES:參數(shù)標志位稳懒,表示檢索出所有有數(shù)據(jù)的目錄的應用程序(主要是卸載的)的信息
  • 出參 表示 PackageInfo的List集合

19闲擦、public abstract List<PackageInfo> getInstalledPackages(int flags, int userId)方法:

獲取具有特定用戶的PackageInfo

代碼在PackageManager.java2406行

    /**
     * Return a List of all packages that are installed on the device, for a specific user.
     * Requesting a list of installed packages for another user
     * will require the permission INTERACT_ACROSS_USERS_FULL.
     * @param flags Additional option flags. Use any combination of
     * {@link #GET_ACTIVITIES},
     * {@link #GET_GIDS},
     * {@link #GET_CONFIGURATIONS},
     * {@link #GET_INSTRUMENTATION},
     * {@link #GET_PERMISSIONS},
     * {@link #GET_PROVIDERS},
     * {@link #GET_RECEIVERS},
     * {@link #GET_SERVICES},
     * {@link #GET_SIGNATURES},
     * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
     * @param userId The user for whom the installed packages are to be listed
     *
     * @return A List of PackageInfo objects, one for each package that is
     *         installed on the device.  In the unlikely case of there being no
     *         installed packages, an empty list is returned.
     *         If flag GET_UNINSTALLED_PACKAGES is set, a list of all
     *         applications including those deleted with {@code DONT_DELETE_DATA}
     *         (partially installed apps with data directory) will be returned.
     *
     * @see #GET_ACTIVITIES
     * @see #GET_GIDS
     * @see #GET_CONFIGURATIONS
     * @see #GET_INSTRUMENTATION
     * @see #GET_PERMISSIONS
     * @see #GET_PROVIDERS
     * @see #GET_RECEIVERS
     * @see #GET_SERVICES
     * @see #GET_SIGNATURES
     * @see #GET_UNINSTALLED_PACKAGES
     *
     * @hide
     */
    public abstract List<PackageInfo> getInstalledPackages(int flags, int userId);

翻譯注釋如下:

  • 返回當前設備上某個用戶的所有安裝軟件的安裝包信息,這里要求一個INTERACT_ACROSS_USERS_FULL權限
  • 入?yún)arams flags 附加選項的標志位僚祷,你可以理解為篩選條件佛致,可以使用的標志位為:
    • GET_ACTIVITIES :(packageInfo的標志)表示 返回包(packageInfo)中包含的所有Activity信息
    • GET_GIDS :(packageInfo的標志)表示 返回關聯(lián)的GID(groupId)
    • GET_CONFIGURATIONS :(packageInfo的標志)表示 配置選項信息
    • GET_INSTRUMENTATION :(PackageInfo的標志)表示 是否使用了instrumentation
    • GET_PERMISSIONS :(PackageInfo的標志)表示 是否使用了permissions
    • GET_PROVIDERS :(PackageInfo的標志)表示 是否使用了providers
    • GET_RECEIVERS :(PackageInfo的標志)表示 是否使用了recevier
    • GET_SERVICES :(PackageInfo的標志)表示 是否使用了service
    • GET_SIGNATURES :(PackageInf的標志) 表示是否使用包的簽名信息
    • GET_UNINSTALLED_PACKAGES:參數(shù)標志位,表示檢索出所有有數(shù)據(jù)的目錄的應用程序(主要是卸載的)的信息
  • 入?yún)arams userId 用戶的id
  • 出參 PackageInfo對象的List集合辙谜,返回的每一個包都是安裝在這個設備上俺榆。如果一個安裝包都沒有,則返回一個空的List装哆,當然這種情況不太可能發(fā)生罐脊。如果設置了GET_UNINSTALLED_PACKAGES標志位,則List包含使用DONT_DELETE_DATA標志的已經(jīng)刪除的應用程序蜕琴。

20萍桌、public abstract List<ApplicationInfo> getInstalledApplications(int flags)方法:

獲取所有已經(jīng)安裝的應用程序集合

代碼在PackageManager.java2746行

    /**
     * Return a List of all application packages that are installed on the
     * device. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all
     * applications including those deleted with {@code DONT_DELETE_DATA} (partially
     * installed apps with data directory) will be returned.
     *
     * @param flags Additional option flags. Use any combination of
     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
     * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
     *
     * @return Returns a List of ApplicationInfo objects, one for each application that
     *         is installed on the device.  In the unlikely case of there being
     *         no installed applications, an empty list is returned.
     *         If flag GET_UNINSTALLED_PACKAGES is set, a list of all
     *         applications including those deleted with {@code DONT_DELETE_DATA}
     *         (partially installed apps with data directory) will be returned.
     *
     * @see #GET_META_DATA
     * @see #GET_SHARED_LIBRARY_FILES
     * @see #GET_UNINSTALLED_PACKAGES
     */
    public abstract List<ApplicationInfo> getInstalledApplications(int flags);

翻譯注釋如下:

  • 返回設備上已經(jīng)安裝的所有應用程序的集合。如果設置了GET_UNINSTALLED_PACKAGES標志位凌简,則集合中包含已經(jīng)設置為DONT_DELETE_DATA的已經(jīng)卸載的應用程序上炎。
  • 入?yún)arams flags 附加選項的標志位,你可以理解為篩選條件雏搂,可以使用的標志位為:
    • GET_META_DATA :ComponentInfo的標志位藕施,返回與該組件(ComponentInfo)相關聯(lián)的(metaData)數(shù)據(jù)(android.os.Bundle)。
    • GET_SHARED_LIBRARY_FILES:ApplicationInfo的標志位凸郑,返回與應用程序關聯(lián)的共享庫(ApplicationInfo路徑)
    • GET_UNINSTALLED_PACKAGES:參數(shù)標志位裳食,表示檢索出所有有數(shù)據(jù)的目錄的應用程序(主要是卸載的)的信息
  • 出參 ApplicationInfo對象的List集合,返回的每一個ApplicationInfo都是安裝在這個設備上芙沥。如果一個安裝ApplicationInfo都沒有诲祸,則返回一個空的List浊吏,當然這種情況不太可能發(fā)生。如果設置了GET_UNINSTALLED_PACKAGES標志位救氯,則List包含使用DONT_DELETE_DATA標志的已經(jīng)刪除的應用程序找田。

六、PackageManager中關于"安裝"的幾個方法

1径密、public abstract void installPackage(Uri, IPackageInstallObserver, int,String)方法:

代碼在PackageManager.java 3586行

    /**
     * @hide Install a package. Since this may take a little while, the result
     *       will be posted back to the given observer. An installation will
     *       fail if the calling context lacks the
     *       {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if
     *       the package named in the package file's manifest is already
     *       installed, or if there's no space available on the device.
     * @param packageURI The location of the package file to install. This can
     *            be a 'file:' or a 'content:' URI.
     * @param observer An observer callback to get notified when the package
     *            installation is complete.
     *            {@link IPackageInstallObserver#packageInstalled(String, int)}
     *            will be called when that happens. This parameter must not be
     *            null.
     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
     *            {@link #INSTALL_REPLACE_EXISTING},
     *            {@link #INSTALL_ALLOW_TEST}.
     * @param installerPackageName Optional package name of the application that
     *            is performing the installation. This identifies which market
     *            the package came from.
     * @deprecated Use {@link #installPackage(Uri, PackageInstallObserver, int,
     *             String)} instead. This method will continue to be supported
     *             but the older observer interface will not get additional
     *             failure details.
     */
    // @SystemApi
    public abstract void installPackage(
            Uri packageURI, IPackageInstallObserver observer, int flags,
            String installerPackageName);

通過代碼我們發(fā)現(xiàn)它是一個 系統(tǒng)API(SystemApi)

翻譯注釋如下:

  • 安裝一個安裝包的時候午阵,需要經(jīng)過一定的時間之后才能把安裝的結果返回一個觀察者。如果在安裝并調(diào)用Context的時候 在android.Manifest.permission缺少INSTALL_PACKAGES權限將會導致安裝失敗享扔。如果設備上已經(jīng)安裝了這個同一個包名的應用程序或者在設備已經(jīng)沒有了合適的空間都會導致安裝失敗底桂。
  • 入?yún)?packageURI :表示安裝的路徑,可以是"file:"或者"content:"的URI
  • 入?yún)?observer :一個回調(diào)的觀察者惧眠,有了這個觀察者籽懦,就可以在軟件包安裝完成后得到安裝結果的通知。如果安裝完成會調(diào)用這個觀察者IPackageInstallObserver的packageInstalled(String氛魁,int)方法暮顺。observer這個入?yún)⒉荒転榭铡?/li>
  • 入?yún)?flags :標志位參數(shù),可能是以下的幾個值
    • INSTALL_FORWARD_LOCK:安裝時候的標志位秀存,表示應用程序為向前鎖定捶码,即僅應用程序本身可以訪問其代碼和非資源的assets
    • INSTALL_REPLACE_EXISTING:安裝時候的標志位,表示如果在設備存在同一個包名的安裝包或链,則你要替換已安裝的軟件包惫恼。
    • INSTALL_ALLOW_TEST:安裝時候的標志位,表示是否允許安裝測試包(在AndroidManifest里面設置了android:testOnly)
  • 入?yún)?installerPackageName :正在進行安裝的安裝包包名
  • 注意事項:不推薦使用這個方法(@deprecated):
    建議使用installPackage(Uri,PackageInstallObserver,int,String)這個方法澳盐,在后續(xù)版本將支持installPackage(Uri,PackageInstallObserver,int,String)這個方法祈纯,因為老版本的observer無法獲得額外的故障細節(jié)。

2叼耙、 public abstract void installPackageWithVerification(Uri,IPackageInstallObserver, int, String,Uri, ManifestDigest,ContainerEncryptionParams);方法:

代碼在PackageManager.java 3624行

    /**
     * Similar to
     * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
     * with an extra verification file provided.
     *
     * @param packageURI The location of the package file to install. This can
     *            be a 'file:' or a 'content:' URI.
     * @param observer An observer callback to get notified when the package
     *            installation is complete.
     *            {@link IPackageInstallObserver#packageInstalled(String, int)}
     *            will be called when that happens. This parameter must not be
     *            null.
     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
     *            {@link #INSTALL_REPLACE_EXISTING},
     *            {@link #INSTALL_ALLOW_TEST}.
     * @param installerPackageName Optional package name of the application that
     *            is performing the installation. This identifies which market
     *            the package came from.
     * @param verificationURI The location of the supplementary verification
     *            file. This can be a 'file:' or a 'content:' URI. May be
     *            {@code null}.
     * @param manifestDigest an object that holds the digest of the package
     *            which can be used to verify ownership. May be {@code null}.
     * @param encryptionParams if the package to be installed is encrypted,
     *            these parameters describing the encryption and authentication
     *            used. May be {@code null}.
     * @hide
     * @deprecated Use {@link #installPackageWithVerification(Uri,
     *             PackageInstallObserver, int, String, Uri, ManifestDigest,
     *             ContainerEncryptionParams)} instead. This method will
     *             continue to be supported but the older observer interface
     *             will not get additional failure details.
     */
    // @SystemApi
    public abstract void installPackageWithVerification(Uri packageURI,
            IPackageInstallObserver observer, int flags, String installerPackageName,
            Uri verificationURI, ManifestDigest manifestDigest,
            ContainerEncryptionParams encryptionParams);

通過代碼我們發(fā)現(xiàn)它是一個 系統(tǒng)API(SystemApi)

翻譯注釋如下:

  • 和installPackage(Uri,IPackageInstallObserver,int,String)方法類似腕窥,就是比它多了一個額外的文件驗證功能
  • 入?yún)?packageURI :表示安裝的路徑,可以是"file:"或者"content:"的URI
  • 入?yún)?observer :一個回調(diào)的觀察者筛婉,有了這個觀察者簇爆,就可以在軟件包安裝完成后得到安裝結果的通知。如果安裝完成會調(diào)用這個觀察者IPackageInstallObserver的packageInstalled(String爽撒,int)方法冕碟。observer這個入?yún)⒉荒転榭铡?/li>
  • 入?yún)?flags :標志位參數(shù),可能是以下的幾個值
    • INSTALL_FORWARD_LOCK:安裝時候的標志位匆浙,表示應用程序為向前鎖定,即僅應用程序本身可以訪問其代碼和非資源的assets
    • INSTALL_REPLACE_EXISTING:安裝時候的標志位厕妖,表示如果在設備存在同一個包名的安裝包首尼,則你要替換已安裝的軟件包。
    • INSTALL_ALLOW_TEST:安裝時候的標志位,表示是否允許安裝測試包(在AndroidManifest里面設置了android:testOnly)
  • 入?yún)?installerPackageName :正在進行安裝的安裝包包名
  • 入?yún)?verificationURI :驗證文件的位置软能,可以是"file:"或者"content:"的URI迎捺,該入?yún)⒖赡転閚ull
  • 入?yún)?manifestDigest :一個包含可用于驗證所有權的包的摘要的對象,該入?yún)⒖赡転閚ull
  • 入?yún)?encryptionParams :一個描述加密和認證狀態(tài)的對象查排,這個入?yún)⒛転閚ull凳枝。
  • 注意事項:不推薦使用這個方法(@deprecated):
    建議使用installPackageWithVerification(Uri,PackageInstallObserver, int, String, Uri, ManifestDigest,ContainerEncryptionParams)這個方法,在后續(xù)版本將支持installPackageWithVerification(Uri,PackageInstallObserver, int, String, Uri, ManifestDigest,ContainerEncryptionParams)這個方法跋核,因為老版本的observer無法獲得額外的故障細節(jié)岖瑰。

3、public abstract void installPackageWithVerificationAndEncryption(Uri,IPackageInstallObserver, int, String, VerificationParams, ContainerEncryptionParams)方法:

代碼在PackageManager.java 3660行

    /**
     * Similar to
     * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
     * with an extra verification information provided.
     *
     * @param packageURI The location of the package file to install. This can
     *            be a 'file:' or a 'content:' URI.
     * @param observer An observer callback to get notified when the package
     *            installation is complete.
     *            {@link IPackageInstallObserver#packageInstalled(String, int)}
     *            will be called when that happens. This parameter must not be
     *            null.
     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
     *            {@link #INSTALL_REPLACE_EXISTING},
     *            {@link #INSTALL_ALLOW_TEST}.
     * @param installerPackageName Optional package name of the application that
     *            is performing the installation. This identifies which market
     *            the package came from.
     * @param verificationParams an object that holds signal information to
     *            assist verification. May be {@code null}.
     * @param encryptionParams if the package to be installed is encrypted,
     *            these parameters describing the encryption and authentication
     *            used. May be {@code null}.
     * @hide
     * @deprecated Use {@link #installPackageWithVerificationAndEncryption(Uri,
     *             PackageInstallObserver, int, String, VerificationParams,
     *             ContainerEncryptionParams)} instead. This method will
     *             continue to be supported but the older observer interface
     *             will not get additional failure details.
     */
    @Deprecated
    public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
            IPackageInstallObserver observer, int flags, String installerPackageName,
            VerificationParams verificationParams,
            ContainerEncryptionParams encryptionParams);

通過代碼我們發(fā)現(xiàn)它是一個 系統(tǒng)API(SystemApi)

翻譯注釋如下:

  • 和installPackage(Uri,IPackageInstallObserver,int,String)方法類似砂代,就是比它多了一個額外的文件驗證功能
  • 入?yún)?packageURI :表示安裝的路徑蹋订,可以是"file:"或者"content:"的URI
  • 入?yún)?observer :一個回調(diào)的觀察者,有了這個觀察者刻伊,就可以在軟件包安裝完成后得到安裝結果的通知露戒。如果安裝完成會調(diào)用這個觀察者IPackageInstallObserver的packageInstalled(String,int)方法捶箱。observer這個入?yún)⒉荒転榭铡?/li>
  • 入?yún)?flags :標志位參數(shù)智什,可能是以下的幾個值
    • INSTALL_FORWARD_LOCK:安裝時候的標志位,表示應用程序為向前鎖定丁屎,即僅應用程序本身可以訪問其代碼和非資源的assets
    • INSTALL_REPLACE_EXISTING:安裝時候的標志位荠锭,表示如果在設備存在同一個包名的安裝包,則你要替換已安裝的軟件包悦屏。
    • INSTALL_ALLOW_TEST:安裝時候的標志位节沦,表示是否允許安裝測試包(在AndroidManifest里面設置了android:testOnly)
  • 入?yún)?installerPackageName :正在進行安裝的安裝包包名
  • 入?yún)?verificationParams :持有驗證信息的對象,可能是null础爬。
  • 入?yún)?encryptionParams :一個描述加密和認證狀態(tài)的對象甫贯,這個入?yún)⒛転閚ull。
  • 注意事項:不推薦使用這個方法(@deprecated):
    建議使用installPackageWithVerification(Uri,PackageInstallObserver, int, String, VerificationParams,ContainerEncryptionParams)這個方法看蚜,在后續(xù)版本將支持installPackageWithVerification(Uri,PackageInstallObserver, int, String, Uri, ManifestDigest,ContainerEncryptionParams)這個方法叫搁,因為老版本的observer無法獲得額外的故障細節(jié)。

4供炎、 public abstract void installPackage(Uri,PackageInstallObserver,int, String)方法:

代碼在PackageManager.java 3688行

    /**
     * @hide
     *
     * Install a package. Since this may take a little while, the result will
     * be posted back to the given observer.  An installation will fail if the calling context
     * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
     * package named in the package file's manifest is already installed, or if there's no space
     * available on the device.
     *
     * @param packageURI The location of the package file to install.  This can be a 'file:' or a
     * 'content:' URI.
     * @param observer An observer callback to get notified when the package installation is
     * complete. {@link PackageInstallObserver#packageInstalled(String, Bundle, int)} will be
     * called when that happens. This parameter must not be null.
     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
     * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
     * @param installerPackageName Optional package name of the application that is performing the
     * installation. This identifies which market the package came from.
     */
    public abstract void installPackage(
            Uri packageURI, PackageInstallObserver observer,
            int flags, String installerPackageName);

翻譯注釋如下:

  • 安裝一個安裝包的時候渴逻,需要經(jīng)過一定的時間之后才能把安裝的結果返回個觀察者。如果在安裝并調(diào)用Context的時候 在android.Manifest.permission缺少INSTALL_PACKAGES權限將會導致安裝失敗音诫。如果設備上已經(jīng)安裝了這個同一個包名的應用程序或者在設備已經(jīng)沒有了合適的空間都會導致安裝失敗们衙。
  • 入?yún)?packageURI :表示安裝的路徑,可以是"file:"或者"content:"的URI
  • 入?yún)?observer :一個回調(diào)的觀察者滞欠,有了這個觀察者,就可以在軟件包安裝完成后得到安裝結果的通知雹洗。如果安裝完成會調(diào)用這個觀察者IPackageInstallObserver的packageInstalled(String,int)方法卧波。observer這個入?yún)⒉荒転榭铡?/li>
  • 入?yún)?flags :標志位參數(shù)时肿,可能是以下的幾個值
    • INSTALL_FORWARD_LOCK:安裝時候的標志位,表示應用程序為向前鎖定港粱,即僅應用程序本身可以訪問其代碼和非資源的assets
    • INSTALL_REPLACE_EXISTING:安裝時候的標志位螃成,表示如果在設備存在同一個包名的安裝包,則你要替換已安裝的軟件包查坪。
    • INSTALL_ALLOW_TEST:安裝時候的標志位寸宏,表示是否允許安裝測試包(在AndroidManifest里面設置了android:testOnly)
  • 入?yún)?installerPackageName :正在進行安裝的安裝包包名

5、public abstract void installPackageWithVerification(Uri,PackageInstallObserver, int, String, Uri, ManifestDigest,ContainerEncryptionParams)方法:

代碼在PackageManager.java 3717行

    /**
     * Similar to
     * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
     * with an extra verification file provided.
     *
     * @param packageURI The location of the package file to install. This can
     *            be a 'file:' or a 'content:' URI.
     * @param observer An observer callback to get notified when the package installation is
     * complete. {@link PackageInstallObserver#packageInstalled(String, Bundle, int)} will be
     * called when that happens. This parameter must not be null.
     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
     *            {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
     * @param installerPackageName Optional package name of the application that
     *            is performing the installation. This identifies which market
     *            the package came from.
     * @param verificationURI The location of the supplementary verification
     *            file. This can be a 'file:' or a 'content:' URI. May be
     *            {@code null}.
     * @param manifestDigest an object that holds the digest of the package
     *            which can be used to verify ownership. May be {@code null}.
     * @param encryptionParams if the package to be installed is encrypted,
     *            these parameters describing the encryption and authentication
     *            used. May be {@code null}.
     * @hide
     */
    public abstract void installPackageWithVerification(Uri packageURI,
            PackageInstallObserver observer, int flags, String installerPackageName,
            Uri verificationURI, ManifestDigest manifestDigest,
            ContainerEncryptionParams encryptionParams);

翻譯注釋如下:

  • 和installPackage(Uri,IPackageInstallObserver,int,String)方法類似咪惠,就是比它多了一個額外的文件驗證功能
  • 入?yún)?packageURI :表示安裝的路徑击吱,可以是"file:"或者"content:"的URI
  • 入?yún)?observer :一個回調(diào)的觀察者,有了這個觀察者遥昧,就可以在軟件包安裝完成后得到安裝結果的通知覆醇。如果安裝完成會調(diào)用這個觀察者IPackageInstallObserver的packageInstalled(String,int)方法炭臭。observer這個入?yún)⒉荒転榭铡?/li>
  • 入?yún)?flags :標志位參數(shù)永脓,可能是以下的幾個值
    • INSTALL_FORWARD_LOCK:安裝時候的標志位,表示應用程序為向前鎖定鞋仍,即僅應用程序本身可以訪問其代碼和非資源的assets
    • INSTALL_REPLACE_EXISTING:安裝時候的標志位常摧,表示如果在設備存在同一個包名的安裝包,則你要替換已安裝的軟件包威创。
    • INSTALL_ALLOW_TEST:安裝時候的標志位落午,表示是否允許安裝測試包(在AndroidManifest里面設置了android:testOnly)
  • 入?yún)?installerPackageName :正在進行安裝的安裝包包名
  • 入?yún)?verificationURI :驗證文件的位置,可以是"file:"或者"content:"的URI肚豺,該入?yún)⒖赡転閚ull
  • 入?yún)?manifestDigest :一個包含可用于驗證所有權的包的摘要的對象溃斋,該入?yún)⒖赡転閚ull
  • 入?yún)?encryptionParams :一個描述加密和認證狀態(tài)的對象,這個入?yún)⒛転閚ull吸申。

6梗劫、public abstract void installPackageWithVerificationAndEncryption(Uri,PackageInstallObserver, int, String,VerificationParams, ContainerEncryptionParams)方法:

代碼在PackageManager.java 3745行

    /**
     * Similar to
     * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
     * with an extra verification information provided.
     *
     * @param packageURI The location of the package file to install. This can
     *            be a 'file:' or a 'content:' URI.
     * @param observer An observer callback to get notified when the package installation is
     * complete. {@link PackageInstallObserver#packageInstalled(String, Bundle, int)} will be
     * called when that happens. This parameter must not be null.
     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
     *            {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
     * @param installerPackageName Optional package name of the application that
     *            is performing the installation. This identifies which market
     *            the package came from.
     * @param verificationParams an object that holds signal information to
     *            assist verification. May be {@code null}.
     * @param encryptionParams if the package to be installed is encrypted,
     *            these parameters describing the encryption and authentication
     *            used. May be {@code null}.
     *
     * @hide
     */
    public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
            PackageInstallObserver observer, int flags, String installerPackageName,
            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams);

翻譯注釋如下:

  • 和installPackage(Uri,IPackageInstallObserver,int,String)方法類似,就是比它多了一個額外的文件驗證功能
  • 入?yún)?packageURI :表示安裝的路徑截碴,可以是"file:"或者"content:"的URI
  • 入?yún)?observer :一個回調(diào)的觀察者梳侨,有了這個觀察者,就可以在軟件包安裝完成后得到安裝結果的通知日丹。如果安裝完成會調(diào)用這個觀察者IPackageInstallObserver的packageInstalled(String走哺,int)方法。observer這個入?yún)⒉荒転榭铡?/li>
  • 入?yún)?flags :標志位參數(shù)哲虾,可能是以下的幾個值
    • INSTALL_FORWARD_LOCK:安裝時候的標志位丙躏,表示應用程序為向前鎖定齐帚,即僅應用程序本身可以訪問其代碼和非資源的assets
    • INSTALL_REPLACE_EXISTING:安裝時候的標志位,表示如果在設備存在同一個包名的安裝包彼哼,則你要替換已安裝的軟件包。
    • INSTALL_ALLOW_TEST:安裝時候的標志位湘今,表示是否允許安裝測試包(在AndroidManifest里面設置了android:testOnly)
  • 入?yún)?installerPackageName :正在進行安裝的安裝包包名
  • 入?yún)?verificationParams :持有驗證信息的對象敢朱,可能是null。
  • 入?yún)?encryptionParams :一個描述加密和認證狀態(tài)的對象摩瞎,這個入?yún)⒛転閚ull拴签。

7、public abstract int installExistingPackage(String)方法:

代碼在PackageManager.java 3755行

    /**
     * If there is already an application with the given package name installed
     * on the system for other users, also install it for the calling user.
     * @hide
     */
    // @SystemApi
    public abstract int installExistingPackage(String packageName)
            throws NameNotFoundException;

翻譯注釋如下:

  • 如果系統(tǒng)上已經(jīng)安裝相同包名的應用程序旗们,則重復重新安裝蚓哩。

上一篇文章 APK安裝流程詳解1——有關"安裝ing"的實體類概述-
下一篇文章 APK安裝流程詳解3——PackageManager與PackageManagerService

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市上渴,隨后出現(xiàn)的幾起案子岸梨,更是在濱河造成了極大的恐慌,老刑警劉巖稠氮,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曹阔,死亡現(xiàn)場離奇詭異,居然都是意外死亡隔披,警方通過查閱死者的電腦和手機赃份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奢米,“玉大人抓韩,你說我怎么就攤上這事△蕹ぃ” “怎么了谒拴?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長痢士。 經(jīng)常有香客問我彪薛,道長,這世上最難降的妖魔是什么怠蹂? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任善延,我火速辦了婚禮,結果婚禮上城侧,老公的妹妹穿的比我還像新娘易遣。我一直安慰自己,他們只是感情好嫌佑,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布豆茫。 她就那樣靜靜地躺著侨歉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪揩魂。 梳的紋絲不亂的頭發(fā)上幽邓,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音火脉,去河邊找鬼牵舵。 笑死,一個胖子當著我的面吹牛倦挂,可吹牛的內(nèi)容都是我干的畸颅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼方援,長吁一口氣:“原來是場噩夢啊……” “哼没炒!你這毒婦竟也來了?” 一聲冷哼從身側響起犯戏,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤送火,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笛丙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漾脂,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年胚鸯,在試婚紗的時候發(fā)現(xiàn)自己被綠了骨稿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡姜钳,死狀恐怖坦冠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哥桥,我是刑警寧澤辙浑,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站拟糕,受9級特大地震影響判呕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜送滞,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一侠草、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧犁嗅,春花似錦边涕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽园爷。三九已至,卻和暖如春式撼,著一層夾襖步出監(jiān)牢的瞬間童社,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工著隆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叠洗,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓旅东,卻偏偏與公主長得像,于是被迫代替她去往敵國和親十艾。 傳聞我的和親對象是個殘疾皇子抵代,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容