getApplicationInfo的坑
一般情況下我們通過(guò)PackageManager.GET_UNINSTALLED_PACKAGES來(lái)檢查應(yīng)用是否安裝狸捅,且不論其本身存在的不正確性,自Android 4.2(API 17)以后超全,多賬戶的出現(xiàn)橘原,其又新出現(xiàn)一些坑”ぃ現(xiàn)在Android 7.0(API 24)使用MATCH_UNINSTALLED_PACKAGES 將其替換县习。
問(wèn)題描述
在做微信分享操作之前掘而,應(yīng)用內(nèi)先對(duì)微信App進(jìn)行一次判斷是否安裝迫悠,使用的方法:
public boolean checkApkExist(Context context, String packageName) {
try {
ApplicationInfo info = context.getPackageManager().getApplicationInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
if (info != null)
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return false;
}
在我的設(shè)備上存在兩個(gè)賬戶鹏漆,一個(gè)管理員賬戶用于日常使用,另一個(gè)普通賬戶用于開(kāi)發(fā)创泄,在我的管理員賬戶中安裝了微信甫男,而普通賬戶里面沒(méi)有安裝微信,但是在普通賬戶里運(yùn)行這段代碼验烧,其會(huì)告訴你安裝了微信板驳。
問(wèn)題分析
從API 24的源碼可以看到,其實(shí)GET_UNINSTALLED_PACKAGES標(biāo)志僅僅用于查詢?cè)谑謾C(jī)系統(tǒng)分區(qū)存在數(shù)據(jù)目錄的應(yīng)用:
/**
* @deprecated replaced with {@link #MATCH_UNINSTALLED_PACKAGES}
*/
@Deprecated
public static final int GET_UNINSTALLED_PACKAGES = 0x00002000;
/**
* Flag parameter to retrieve some information about all applications (even
* uninstalled ones) which have data directories. This state could have
* resulted if applications have been deleted with flag
* {@code DONT_DELETE_DATA} with a possibility of being replaced or
* reinstalled in future.
* <p>
* Note: this flag may cause less information about currently installed
* applications to be returned.
*/
public static final int MATCH_UNINSTALLED_PACKAGES = 0x00002000;
其實(shí)這個(gè)標(biāo)簽都不一定能保證應(yīng)用就一定安裝著碍拆,只能說(shuō)應(yīng)用是否安裝過(guò)若治,而多賬戶下就更不能保證這個(gè)賬戶下就一定安裝過(guò)了,因?yàn)榭梢允橇硪粋€(gè)賬戶下安裝過(guò)感混。
問(wèn)題解決
- 盡量不要使用GET_UNINSTALLED_PACKAGES或者M(jìn)ATCH_UNINSTALLED_PACKAGES去判斷應(yīng)用是否已安裝或者安裝過(guò)端幼。
- 微信的API自有判斷是否安裝的方法。