java解析apk報錯 Expected chunk of type 0x80003, read 0x80001.
阿新 • • 發佈:2018-12-03
業務需求:web頁面上傳一個apk,java後端讀取apk資訊展現。
傳統的讀取apk方式:用zip解壓讀取AndroidManifest.xml中的配置資訊。
上述讀取方式不能適用於所有市面上的apk,遇到某些金融類等等apk需要用aapt工具才能讀取。
linux下無法使用aapt.exe讀取方式,估附帶Linux安裝aapt教程。
linux下載安裝aapt工具
java整合aapt讀取apk資訊(直接貼程式碼了,只貼了業務需要的讀取的apk資訊,並非全部)
import com.skr.mdm.util.ReadApk; import net.sf.json.JSONObject; import java.io.*; import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; public class AaptUtil { private ProcessBuilder mBuilder; private static final String SPLIT_REGEX = "(: )|(=')|(' )|'"; /** * aapt所在的目錄。 */ private String mAaptPath = "src/main/java/com/xxx/xxx/utils/apk/aapt/aapt.exe"; public AaptUtil() { if (System.getProperty("os.name").equals("Linux")) mAaptPath = "/usr/local/apktool/aapt" ; mBuilder = new ProcessBuilder(); mBuilder.redirectErrorStream(true); } public static void main(String[] args) throws Exception { System.out.println(JSONObject.fromObject(new AaptUtil().readApk("C:\\Users\\hx\\Desktop\\xxx.apk")).toString()); } public Map<String, Object> readApk(String apkPath) throws Exception { Map<String, Object> apkInfoMap = new HashMap<String, Object>(); return getApkInfo(apkInfoMap, apkPath); } /** * 返回一個apk程式的資訊。 * * @param apkPath apk的路徑。 * @return apkInfoMap 一個Apk的資訊。 */ public Map<String, Object> getApkInfo(Map<String, Object> apkInfoMap, String apkPath) throws Exception { //通過命令呼叫aapt工具解析apk檔案 Process process = mBuilder.command(mAaptPath, "d", "badging", apkPath).start(); InputStream is = null; is = process.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf8")); String tmp = br.readLine(); try { if (tmp == null || !tmp.startsWith("package")) throw new Exception("引數不正確,無法正常解析APK包。輸出結果為:\n" + tmp + "..."); do { setApkInfoProperty(apkInfoMap, tmp); } while ((tmp = br.readLine()) != null); return apkInfoMap; } catch (Exception e) { throw e; } finally { process.destroy(); closeIO(is); closeIO(br); } } /** * 設定APK的屬性資訊。 * * @param apkInfoMap * @param source */ private void setApkInfoProperty(Map<String, Object> apkInfoMap, String source) { if (source.startsWith("package")) splitPackageInfo(apkInfoMap, source); } /** * 分離出包名、版本等資訊。 * * @param apkInfoMap * @param packageSource */ private void splitPackageInfo(Map<String, Object> apkInfoMap, String packageSource) { String[] packageInfo = packageSource.split(SPLIT_REGEX); apkInfoMap.put("apkPackageName", packageInfo[2]) ; apkInfoMap.put("versionCode", packageInfo[4]) ; apkInfoMap.put("apkVersion", packageInfo[6]) ; } /** * 釋放資源。 * * @param c 將關閉的資源 */ private final void closeIO(Closeable c) { if (c != null) { try { c.close(); } catch (IOException e) { e.printStackTrace(); } } } }