Читайте манифест из третьего приложения

Я пытаюсь прочитать манифест третьего приложения в моем эмуляторе, поэтому я использовал PackageManager для вывода списка всех приложений, а затем выбрал случайное приложение для чтения его манифеста. Проблема в том, что он возвращает плохие символы, подобные этому:

����>����r��������������������������������������l�����

Есть моя функция листинга:

val apps = context.packageManager.getInstalledApplications(PackageManager.GET_META_DATA or PackageManager.GET_SHARED_LIBRARY_FILES)

for (i in 0 until apps.size)
{
    Log.i("List", "Application $i = ${apps[i]}")

    if (i == 80)
    {
        val content = readManifest(apps[i].publicSourceDir)
    }
}

И есть моя функция, где я пытаюсь прочитать манифест:

private fun readManifest(path: String): String
{
    Log.i("readManifest", "path = $path")

    val apk = ZipFile(path)
    val manifest = apk.getEntry("AndroidManifest.xml")
    val stream = apk.getInputStream(manifest)
    val content = StringBuilder()

    if (manifest != null)
    {
        val bufferedReader = BufferedReader(InputStreamReader(apk.getInputStream(manifest), "utf-8"))
        var line = bufferedReader.readLine()
        while (line != null)
        {
            Log.i("readManifest", "line = $line")
            content.append(line)
            line = bufferedReader.readLine()
        }
    }

    apk.close()
    stream.close()

    return content.toString()
}

Я также попытался использовать другую функцию, которую нашел здесь, но с тем же результатом.

Почему я получаю этих странных персонажей? Я также поместил android.permission.READ_EXTERNAL_STORAGE в свой манифест

2 ответа

Решение

После некоторого исследования формата apk кажется, что Manifest скомпилирован в файле apk. Вот почему я не мог прочитать это.

Чтобы прочитать его, мы должны декомпилировать apk раньше, либо с помощью библиотеки (которую я не смог найти), либо при ее кодировании.

проверьте это, получите читаемый androidmanifest

          if (fileName.endsWith(".apk") || fileName.endsWith(".zip")) {
        String entryName = args.length > 1? args[1] : "AndroidManifest.xml";
        zip = new ZipFile(fileName);
        ZipEntry entry = zip.getEntry(entryName);
        is = zip.getInputStream(entry);
    } else {
        is = new FileInputStream(fileName);
    }

    try {
        Document doc = new CompressedXmlParser().parseDOM(is);
        dumpNode(doc.getChildNodes().item(0), "");
    }
    catch (Exception e) {
        System.err.println("Failed AXML decode: " + e);
        e.printStackTrace();
    }

    is.close();
    if (zip != null) {
        zip.close();
    }
}

private static void dumpNode(Node node, String indent) {
    System.out.println(indent + node.getNodeName() + " " + attrsToString(node.getAttributes()) + " -> " + node.getNodeValue());
    NodeList children = node.getChildNodes();
    for (int i = 0, n = children.getLength(); i < n; ++i)
        dumpNode(children.item(i), indent + "   ");
}

private static String attrsToString(NamedNodeMap attrs) {
    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (int i = 0, n = attrs.getLength(); i < n; ++i) {
        if (i != 0)
            sb.append(", ");
        Node attr = attrs.item(i);
        sb.append(attr.getNodeName() + "=" + attr.getNodeValue());
    }
    sb.append(']');
    return sb.toString();
}
Другие вопросы по тегам