zoukankan      html  css  js  c++  java
  • C#实现APK自动打包

    C#实现APK自动打包

        最近做了一个安卓项目,其中有一个自动打包的功能,要把供应商id写入APK后打包。
     

    一、思路

        在AndroidMinifest.xml中加入一个标识字段,如下配置<meta-data android:name="Vendorid" android:value="xx" />,把每个供应商的Id值写到android:value这里,然后用命令行打包。 
     

    二、准备工作

        用到的工具有Android SDKApache-AntJDK1.7。   
        1,安装JDK 1.7(默认安装在C:Program FilesJava)。安装完成后,添加环境变量JAVA_HOME,值就是Javajdk1.7.0_25的实际路径(如果是默认安装的话,那就是 C:Program FilesJavajdk1.7.0_25 )。
        2,建一个文件夹(本文中是建在D盘,D:apktools),然后把Android SDK目录下的platforms、platform-tools、tools这三个文件夹,以及解压后的Apache ant拷贝到D:apktools。
        3,APK源代码我是放在D:src目录下。
     

    三、测试 - 用命令行打包

        做这一步是为了测试之前的准备工作是否做对了。
        1,cd /d D:src,cd到源代码的文件夹
        2,D:apktools oolsandroid.bat update project -n ButtonDemo -t android-17 -p d:src这个批处理可以生成一个工程,工程里配置build.xml脚本。其中,-n ButtonDemo:项目名称、-t android-17:我这里使用android-17这个版本、-p d:src:输出到代码目录下。
        3,D:apktoolsapache-ant-1.9.1inant.bat debug
        4,D:apktoolsapache-ant-1.9.1inant.bat release,编译成功后命令行会显示BUILD SUCCESSFUL。
        
     

    四、代码实现

        最初的代码如下:
    private void Package()
    {
        Process pcmd = new Process();
        pcmd.StartInfo.FileName = "cmd.exe";
        pcmd.StartInfo.UseShellExecute = false;
        pcmd.StartInfo.RedirectStandardInput = true;
        pcmd.StartInfo.RedirectStandardOutput = true;
        pcmd.StartInfo.CreateNoWindow = true;
        pcmd.Start();
        pcmd.StandardInput.Write("cd /d D:src");
        pcmd.StandardInput.WriteLine("");
        pcmd.StandardInput.Write("D:apktools oolsandroid.bat update project -n ButtonDemo -t android-17 -p d:src");
        pcmd.StandardInput.WriteLine("");
        pcmd.StandardInput.Write("D:apktoolsapache-ant-1.9.1inant.bat debug");
        pcmd.StandardInput.WriteLine("");
        pcmd.StandardInput.Write("D:apktoolsapache-ant-1.9.1inant.bat release");
        pcmd.StandardInput.WriteLine("");
     
        pcmd.StandardInput.WriteLine("exit");
     
        string stroutput = pcmd.StandardOutput.ReadToEnd();
    }
     
        调试时发现,ant.bat debug这一步出错,说是JAVA_HOME配置的不对,提示的路径和我实际配置的不一样。必应了一把,看到这篇这篇,大致上就是说UseShellExecute=false方式启动的进程不能访问环境变量,要改成UseShellExecute=true,但是在true的时候,不能重定向输入输出异常这几个了(RedirectStandardInput、RedirectStandardOutput、RedirectStandardError),原先启动cmd.exe,然后输入命令行的方式就行不通了。
        调整了下思路,把这几个命令写成一个批处理,然后Process执行这个批处理就可以了。
    cd /d D:src
    call D:apktools oolsandroid.bat update project -n ButtonDemo -t android-17 -p d:src > {log}
    call D:apktoolsapache-ant-1.9.1inant.bat debug >> {log}
    call D:apktoolsapache-ant-1.9.1inant.bat release >> {log}
    由于不能用RedirectStandardOutput=true来获取输出信息,所以这里我用了dos命令 >> {log}来输出。
     
        最终的打包代码如下:
    private bool Package()
    {
        //先删除编译后的文件,执行完批处理后,通过判断文件存在与否来确定打包是否成功
        string releaseFile = "d:srcButtonDemo-release.apk";
        if (File.Exists(releaseFile))
        {
            File.Delete(releaseFile);
        }
     
        //生成批处理命令D:package.bat
        CreateBatFile();
     
        ProcessStartInfo pi = new ProcessStartInfo();
        pi.FileName = "D:package.bat";
        pi.UseShellExecute = true;
        pi.CreateNoWindow = true;
        Process pcmd = Process.Start(pi);
        //等待进程结束
        while (pcmd.HasExited == false)
        {
            pcmd.WaitForExit(1000);
        }
     
        pcmd.Close();
        pcmd.Dispose();
     
        if(!File.Exists(releaseFile))
        {
            //打包失败
            return false;
        }
        //打包成功
        return true;
    }
        
    AndroidManifest.xml中添加meta-data节点的代码
    private void InsertVendorXmlElememnt()
    {
        List<string> androidnames = new List<string>();
        string xmlfile = @"AndroidManifest.xml";
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.Load(_androidSourcePath + xmlfile);
        XmlNode xmlApp = xmldoc.SelectSingleNode("//application");
        XmlNodeList xmlnodes = xmlApp.SelectNodes("//meta-data");
        foreach (XmlNode item in xmlnodes)
        {
            if (!androidnames.Contains(item.Attributes["android:name"].Value))
            {
                androidnames.Add(item.Attributes["android:name"].Value);
            }
        }
        if (!androidnames.Contains("vendorid"))
        {
            XmlElement xmlelemember = xmldoc.CreateElement("meta-data");
            XmlAttribute memAttr = xmldoc.CreateAttribute("android", "name", "http://schemas.android.com/apk/res/android");
            memAttr.Value = "vendorid";
            xmlelemember.SetAttributeNode(memAttr);
     
            XmlAttribute memValue = xmldoc.CreateAttribute("android", "value", "http://schemas.android.com/apk/res/android");
            memValue.Value = "";
            xmlelemember.SetAttributeNode(memValue);
            xmlApp.AppendChild(xmlelemember);
        }
        xmldoc.Save("d:srcAndroidManifest.xml");
    }
     
     
     
     
     
        




  • 相关阅读:
    golang中os/user包用法
    golang中os包用法
    与table有关的布局
    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version
    canvas里调用getImageData的报security的问题
    CSS样式覆盖规则
    windows7文件夹怎样默认图片大图显示?
    Jboss,Tomcat 远程调试配置
    IE(IE6/IE7/IE8)支持HTML5标签
    JS 继承(类式 与 原型式)
  • 原文地址:https://www.cnblogs.com/wordmy/p/3238009.html
Copyright © 2011-2022 走看看