Java如何解析安卓配置文件Manifest.xml

最近在写和移动端相关的项目,所以无聊写了个配置文件解析工具类
1、引入apk解析jar包依赖

         <dependency>
            <groupId>net.dongliu</groupId>
            <artifactId>apk-parser</artifactId>
            <version>2.5.0</version>
        </dependency>

2、解析工具类书写

package com.example.demo.utils;

import net.dongliu.apk.parser.AbstractApkFile;
import net.dongliu.apk.parser.bean.ApkSignStatus;
import net.dongliu.apk.parser.utils.Inputs;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
     * 分析APK文件,取得APK文件中的 包名、版本号及图标
     * @author wzy
     * @return
     * @date 2018/9/17
     **/
    public class ApkUtil extends AbstractApkFile implements Closeable {
        private final ZipFile zf;
        private File apkFile;

        public ApkUtil(File apkFile) throws IOException {
            this.apkFile = apkFile;
            this.zf = new ZipFile(apkFile);
        }

        public ApkUtil(String filePath) throws IOException {
            this(new File(filePath));
        }

        @Override
        protected List<CertificateFile> getAllCertificateData() throws IOException {
            Enumeration<? extends ZipEntry> enu = zf.entries();
            List<CertificateFile> list = new ArrayList<>();
            while (enu.hasMoreElements()) {
                ZipEntry ne = enu.nextElement();
                if (ne.isDirectory()) {
                    continue;
                }
                String name = ne.getName().toUpperCase();
                if (name.endsWith(".RSA") || name.endsWith(".DSA")) {
                    list.add(new CertificateFile(name, Inputs.readAll(zf.getInputStream(ne))));
                }
            }
            return list;
        }

        @Override
        public byte[] getFileData(String path) throws IOException {
            ZipEntry entry = zf.getEntry(path);
            if (entry == null) {
                return null;
            }
            InputStream inputStream = zf.getInputStream(entry);
            return Inputs.readAll(inputStream);
        }

        @Override
        protected ByteBuffer fileData() throws IOException {
            FileChannel channel = new FileInputStream(apkFile).getChannel();
            return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
        }

        @Override
        @Deprecated
        public ApkSignStatus verifyApk() throws IOException {
            ZipEntry entry = zf.getEntry("META-INF/MANIFEST.MF");
            if (entry == null) {
                // apk is not signed;
                return ApkSignStatus.notSigned;
            }

            try (JarFile jarFile = new JarFile(this.apkFile)) {
                Enumeration<JarEntry> entries = jarFile.entries();
                byte[] buffer = new byte[8192];

                while (entries.hasMoreElements()) {
                    JarEntry e = entries.nextElement();
                    if (e.isDirectory()) {
                        continue;
                    }
                    try (InputStream in = jarFile.getInputStream(e)) {
                        // Read in each jar entry. A security exception will be thrown if a signature/digest check fails.
                        int count;
                        while ((count = in.read(buffer, 0, buffer.length)) != -1) {
                            // Don't care
                        }
                    } catch (SecurityException se) {
                        return ApkSignStatus.incorrect;
                    }
                }
            }
            return ApkSignStatus.signed;
        }

        @Override
        public void close() throws IOException {
            super.close();
            zf.close();
        }
    }

3、解析demo
例如 我们要获取D:XXX.apk 配置文件内的自定义属性
在这里插入图片描述

 /**
     * 文章——上传
     *
     * @param file
     * @return
     */
    @GetMapping("/upload")
    public void upLoadArticle(@RequestParam(value = "file") MultipartFile file) throws Exception {
        if (Objects.requireNonNull(file.getOriginalFilename()).endsWith(".apk")) {
            String filePath = "D:\\";
            File file1  = new File(filePath+file.getOriginalFilename());
            ApkUtil apkUtil = new ApkUtil(file1);
            String manifestXml = apkUtil.getManifestXml();
         //解析xml文档 获取对应的环境URL字段
        org.json.JSONObject xmlJSONObj = XML.toJSONObject(manifestXml);
        Object manifest = xmlJSONObj.get("manifest");
        Map map = JSONObject.parseObject(manifest.toString(), Map.class);
        List list = (List) map.get("meta-data");
        AppInfoBO appInfoBO = new AppInfoBO();
        Object result = null;
        if(CollectionUtils.isEmpty(list)){
            appInfoBO.setDeployUrl("");
        }else {
            Map<String, Object> metadata = (Map<String, Object>) list.get(0);
            if (CollectionUtils.isEmpty(metadata)) {
                appInfoBO.setDeployUrl("");
            }
            result = metadata.get("android:value");
            if (result == null) {
                appInfoBO.setDeployUrl("");
            } else {
                appInfoBO.setDeployUrl(result.toString());
            }
        }
            IpaUtils reader = new IpaUtils(file1);
             reader.parse();
        }
    }

结果:
在这里插入图片描述
当然 还有pull,dom,sax,jdom,dom4j这几种方式解析

发布了47 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42083036/article/details/104626248