Each time our new android app released, I need to update app info on our website. So I try to update the app info automatically, by read the AndroidManifest.xml
in the apk when uploaded to server.
I use AXMLResource
and jdom2
to get the AndroidManifest.xml
and parse it.
final Namespace NS = Namespace.getNamespace("http://schemas.android.com/apk/res/android");
zipFile = new ZipFile(apkPath);
ZipEntry zipEntry = new ZipEntry("AndroidManifest.xml");
inputStream = zipFile.getInputStream(zipEntry);
AXMLResource axmlResource = new AXMLResource();
axmlResource.read(inputStream);
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(new ByteArrayInputStream(axmlResource.toXML().toString().getBytes("UTF-8")));
Element root = document.getRootElement();
System.out.println(root.getAttributeValue("versionCode",NS));
System.out.println(root.getAttributeValue("versionName",NS));
But I always get,
The prefix “data” for attribute “data:versionCode” associated with an element type “manifest” is not bound
And I print the AndroidManifest.xml
,and found the data
namespace is unclared.
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
data:versionCode="344"
data:versionName="3.2.8"
When I check android studio doc and found there use declared namespace.
Then I think this may be caused by our app developers's Irregularities.
But when I think further, why app with AndroidManifest.xml
with undeclared namespace can released, then I download some apks like facebook,youtube,centos,baidu disk and alipay, and found only centos doesn't use undeclared namespace.
For com.google.android.youtube.apk
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
http:versionCode="1425572340"
http:versionName="14.25.57"
The prefix “http” for attribute “http:versionCode” associated with an element type “manifest” is not bound
For com.facebook.katana-225.0.0.47.118.apk
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
manifest:versionCode="158425934"
manifest:versionName="225.0.0.47.118"
The prefix “manifest” for attribute "manifest:versionCode” associated with an element type “manifest” is not bound
So here is comman to use undeclased namespace in AndroidManifest.xml
,but how can I pase it?
Technically your file is well-formed XML but not namespace-well-formed XML. The vast majority of modern XML tools will only handle (or produce) XML that is namespace-well-formed. But if you can find an XML parser that still handles XML that is not namespace-well-formed, then you can use this to "repair" your XML in some way that meets your needs (for example, you could replace manifest:versionCode
by manifest-versionCode
).
However, rather than repairing the XML in this way, it would be much better to create namespace-well-formed XML in the first place, so you're not constrained in your choice of tools.
Your problem is not with namespacing. It's with prefixing. Try changing:
final Namespace NS = Namespace.getNamespace("http://schemas.android.com/apk/res/android");
to this:
final Namespace NS = Namespace.getNamespace("data", "http://schemas.android.com/apk/res/android");
Not having seen the associated schema, I can't tell if the namespaced schema contains a matching attribute descriptor on the manifest
element. I don't know if some of the classes do transparent schema validation. You don't seem to be doing it explicitly in your code so this may be moot.
Somewhere in the data that you receive from these sources, they should tell you what the prefix is that they're using (e.g., "data," "manifest," "http," etc.) in their definition. That'll save you having to hard-code in the, "data," prefix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With