1. 程式人生 > >獲取已安裝或未安裝的apk簽名

獲取已安裝或未安裝的apk簽名

某些時候需要獲取已安裝的apk或者是未安裝的apk的簽名信息,以下程式碼片段將會很有用。
1.通過app的packageName獲取已安裝的apk的簽名信息

public Signature getPackageSignature(Context context, String packageName){
                PackageManager pm = context.getPackageManager();
                List<PackageInfo> apps = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);

                Iterator<PackageInfo> it = apps.iterator();
                while(it.hasNext()){
                        PackageInfo info = it.next();
                        if(info.packageName.equals(packageName)){
                                return info.signatures[0];
                        }

                }
                return null;
        }

2.根據檔案路徑獲取未安裝的apk的簽名信息
由於android平臺本身的一個小bug,使用PackageManager方式獲取未安裝的apk檔案的簽名會稍微費事一點。
(android平臺的這個小bug有些狗血,是因為PackageManager的的getPackageArchiveInfo中少了如下程式碼的原因導致)
缺少的程式碼:

if ((flags & GET_SIGNATURES) != 0)
            packageParser.collectCertificates(pkg, 0);

問題的詳細資訊可以檢視以下連結:
https://code.google.com/p/android/issues/detail?id=9151#c8
https://android-review.googlesource.com/#/c/18769/1/core/java/android/content/pm/PackageManager.java

這樣一來,獲取apk檔案的簽名方式將會變得稍微囉嗦一點
(1)首先自定義一個getPackageArchiveInfo函式,如下:
@SuppressWarnings("unchecked")
        public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags){
        // Workaround for https://code.google.com/p/android/issues/detail?id=9151#c8
        try{
            Class packageParserClass = Class.forName(
                    "android.content.pm.PackageParser");
            Class[] innerClasses = packageParserClass.getDeclaredClasses();
            Class packageParserPackageClass = null;
            for (Class innerClass : innerClasses){
                if (0 == innerClass.getName().compareTo("android.content.pm.PackageParser$Package")){
                    packageParserPackageClass = innerClass;
                    break;
                }
            }
            Constructor packageParserConstructor = packageParserClass.getConstructor(
                    String.class);
            Method parsePackageMethod = packageParserClass.getDeclaredMethod(
                    "parsePackage", File.class, String.class, DisplayMetrics.class, int.class);
            Method collectCertificatesMethod = packageParserClass.getDeclaredMethod(
                    "collectCertificates", packageParserPackageClass, int.class);
            Method generatePackageInfoMethod = packageParserClass.getDeclaredMethod(
                    "generatePackageInfo", packageParserPackageClass, int[].class, int.class, long.class, long.class);
            packageParserConstructor.setAccessible(true);
            parsePackageMethod.setAccessible(true);
            collectCertificatesMethod.setAccessible(true);
            generatePackageInfoMethod.setAccessible(true);

            Object packageParser = packageParserConstructor.newInstance(archiveFilePath);

            DisplayMetrics metrics = new DisplayMetrics();
            metrics.setToDefaults();

            final File sourceFile = new File(archiveFilePath);

            Object pkg = parsePackageMethod.invoke(
                    packageParser,
                    sourceFile,
                    archiveFilePath,
                    metrics,
                    0);
            if (pkg == null){
                return null;
            }

            if ((flags & android.content.pm.PackageManager.GET_SIGNATURES) != 0){
                collectCertificatesMethod.invoke(packageParser, pkg, 0);
            }

            return (PackageInfo)generatePackageInfoMethod.invoke(null, pkg, null, flags, 0, 0);
        }
        catch (Exception e)
        {
            Log.e("Signature Monitor",
                "android.content.pm.PackageParser reflection failed: " + e.toString());
        }

        return null;
    }
(2)使用自定義的getPackageArchiveInfo函式獲取PackageInfo,從而獲取簽名信息,如下:
/**
         * 
         * @param context
         * @param apkFile 檔案的全路徑資訊(包括apk檔案的名稱),如果是無效的apk檔案,返回值為null
         * @return
         */
        public Signature getApkSignatureByFilePath(Context context, String apkFile){
                PackageInfo newInfo = getPackageArchiveInfo(apkFile, PackageManager.GET_ACTIVITIES | PackageManager.GET_SIGNATURES);
                if(newInfo != null){
                        if(newInfo.signatures != null && newInfo.signatures.length >0){
                                return newInfo.signatures[0];
                        }
                }
                return null;
        }

相關推薦

獲取安裝安裝apk簽名

某些時候需要獲取已安裝的apk或者是未安裝的apk的簽名信息,以下程式碼片段將會很有用。1.通過app的packageName獲取已安裝的apk的簽名信息public Signature getPackageSignature(Context context, String

Android之引用其它安裝安裝apk檔案的資源

Android應用有時候會涉及到面板的更換問題,在這裡,我用一種引用其它已安裝或未安裝apk檔案的資源來說明。 其核心思想就是利用反射來獲取。 a、引用其它未安裝apk檔案的資源來說明        1、首先建立一個application(StyleClient),將其打

最可能的原因使用的托管的處理程序,但是安裝完整安裝asp.net

托管 pos tex spa exe lin mil 完整 title 在IIS中訪問APS頁面時提示: “最可能的原因使用的托管的處理程序,但是未安裝或未完整安裝asp.net“ 打開CMD窗口,執行下面的命令: "%WINDIR%\Microsoft.NET\Fr

IIS安裝報錯:使用了託管處理程式,但是安裝完整安裝 ASP.NET

今天在使用IIS部署網站的時候,出現如下錯誤, 解決方案: 開啟CMD視窗,執行以下命令: "%WINDIR%\Microsoft.NET\Framework\v4.0.30319\as

jquery獲取選擇和選擇的checkBox項以及清空所選項

獲取已選中的: var checkedArr = []; $("input[name='xxx']:checked").each(function() { checkedArr.push($(this).val()); }); 獲取未選中的: var notCheckedA

Windows平臺下安裝解除安裝Apache服務

相信很多人都要在日常生活中用到apache伺服器,網上教程說很簡單什麼的,但是也要看個人電腦環境。我就是在折騰了快兩個小時下才整明白,這篇帖子應該會幫到很多人。 安裝 下載資源包1.在此處下載 2.然後,選擇你要下載的版本,點選該連結: 3.因為我的是Windows

安裝sqlserver 的時候 報錯:無法通過Windows功能控制面板自動安裝解除安裝Windows Server 角色和功能。

無法安裝以下功能:.NET Framework 3.5(包括.NET2.0和3.0) 無法通過Windows功能控制面板自動安裝或解除安裝Windows Server 角色和功能。 若要安裝Windows Server 角色和功能,請啟動伺服器管理器,或使用

MySQL 5 安裝解除安裝引發的錯誤解決

MySQL 5.1 安裝過程中報apply security setting錯誤的解決辦法   1, 解除安裝MySQL   2, 刪除目錄 C:/Documents and Settings/All Users/Application Data/MySQL   3, 重新

安裝解除安裝SQL Server 2008時,提示“安裝程式支援規則---重新啟動計算機”失敗的解決辦法

剛才在解除安裝SQL Server 2008時,提示“安裝程式支援規則---重新啟動計算機”失敗,於是按提示重新啟動了一次,再來解除安裝,依然如故。 於是google了下解決方法。 很簡單,開啟登錄檔,找到: 鍵路徑:HKEY_LOCAL_MACHINE/SYSTEM/C

如何在Windows平臺下安裝解除安裝Apache服務

安裝 下載資源包 在下載連結(<–點這裡)處下載:  然後,選擇你要下載的版本,我選擇的是最新版:2.4.16,點選該連結:  因為我的是Windows平臺,所以我選擇:Files for Microsoft Windows,繼續點選:  此處,有

通過命令列安裝解除安裝tomcat服務

      當我們在windows伺服器上部署Java Web程式的時候,我們大多數情況下使用tomcat,並且將tomcat作為服務來啟動、重啟或者停止,那麼在windows的伺服器上如何使用命令進行

Android菜鳥筆記- 獲取安裝APK圖標、版本號、包名、名稱、是否安裝安裝、打開

ack ear 例如 start true intent ble post oca 周末閑來無事,把Android的基礎知識拿出來復習復習,今天主題是《獲取未安裝的APK圖標、版本號、包名、名稱、是否安裝、跳轉安裝、打開》 一、獲取APK圖標 通常讀取APK的圖標能夠用

安裝apk檔案資訊獲取

一、獲取APK圖示 通常讀取APK的圖示可以用,PackageManager裡面的getApplicationIcon(ApplicationInfo)來得到一個drawable。但實際使用的時候經常只能得到一個預設的圖示,根本不是APK的圖示。 參考小米開原始檔管理器,結合實踐,程式

PHPcms V9 新新增模組 提示 phpcms v9 此模組安裝禁用

新建PHPCMS V9模組的時候出現了這個問題–此模組已禁用或未安裝,檢視程式碼,沒有發現問題,也更新了快取,問題依舊,後面想了想,在_module表裡新增一個新條目,寫上新建的模組就好。 1、要在 phpcms 的 _module  表裡新增對應的模組的名字   就是

AutoCAD 許可管理器不起作用,正確安裝,現在將關閉

選擇 分享 log eight src ref 問題 通過 重新安裝 問題描述 重新安裝了也還是這樣,而且第二次打開都跳不出申請碼界面就關閉了。 問題原因,初步認為:AutoCAD 在首次彈出申請激活類型的類型時,直接選擇了網絡激活,而且沒有激活成功。再

Linux-rpm命令-查看安裝軟件包信息及安裝rpm包信息

linux rpm 博文說明【前言】: 本文將通過個人口吻介紹rpm命令,包括查看已安裝軟件包信息及未安裝rpm包信息。 在目前時間點【2017年6月12號】下,所掌握的技術水平有限,可能會存在不少知識理解不夠深入或全面,望大家指出問題共同交流,在後續工作及學習中如發現本文內容與實際情況有

在windows sever2012安裝web服務器時出現“無法打開運行空間池。服務器管理器 WinRM 插件可能損壞丟失”

-1 內存 初始 開啟 man 系統設置 方法 無法 高級 解決方法 方法一:如果是沒有打開WinRM服務 第一步:在服務器中選擇“工具”--“服務” 第二步:找到Windows Remote Mangement服務,如果沒打開,選擇開啟。 方法二:如果上面的服務打

VS 指定的平臺工具集(v141)安裝無效

工具集 vs場景 error MSB8008: 指定的平臺工具集(v141)未安裝或無效。請確保選擇受支持的 PlatformToolset 值環境 平臺工具集:Visual Studio 2015 (v140) Visual Studio 2015 編輯錯誤,是缺少了v141組件解決方法:

Android Studio 2.3 以後給apk簽名打包後安裝失敗的問題

本人java小白,最近一直在學習java,然後接觸到AS,apk簽名打包完成並顯示打包成功(具體簽名步驟看Android Studio 程式簽名打包),在驗證簽名打包是否真的成功,發現結果顯示沒有簽名。如下圖: 谷歌搜尋了一些解決方法,發現 官網上的解釋: 標紅的地方已經提到

華鼎信科技 HD-USB480-II 驅動無法安裝, 提示簽名

windows7 x64bit 的系統對驅動簽名檢測嚴, 該廠商沒有去微軟做認證, 詢問廠商後, 只有在重啟電腦按F8, 進去高階啟動選項, 選擇最後的禁用驅動程式簽名強制, 來啟動電腦, 才能使用該驅動, 重啟後,正常啟動該驅動又會不行, 也就是說,每次使用這個