getApplicationInfo的坑
一般情況下我們通過PackageManager.GET_UNINSTALLED_PACKAGES來檢查應(yīng)用是否安裝,且不論其本身存在的不正確性,自Android 4.2(API 17)以后,多賬戶的出現(xiàn),其又新出現(xiàn)一些坑?,F(xiàn)在Android 7.0(API 24)使用MATCH_UNINSTALLED_PACKAGES 將其替換。
問題描述
在做微信分享操作之前,應(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è)普通賬戶用于開發(fā),在我的管理員賬戶中安裝了微信,而普通賬戶里面沒有安裝微信,但是在普通賬戶里運(yùn)行這段代碼,其會(huì)告訴你安裝了微信。
問題分析
從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)用就一定安裝著,只能說應(yīng)用是否安裝過,而多賬戶下就更不能保證這個(gè)賬戶下就一定安裝過了,因?yàn)榭梢允橇硪粋€(gè)賬戶下安裝過。
問題解決
- 盡量不要使用GET_UNINSTALLED_PACKAGES或者M(jìn)ATCH_UNINSTALLED_PACKAGES去判斷應(yīng)用是否已安裝或者安裝過。
- 微信的API自有判斷是否安裝的方法。