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 Files\Java)。安装完成后,添加环境变量JAVA_HOME,值就是Java\jdk1.7.0_25\的实际路径(如果是默认安装的话,那就是 C:\Program Files\Java\jdk1.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\tools\android.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:\apktools\apache-ant-1.9.1\bin\ant.bat debug
    4,D:\apktools\apache-ant-1.9.1\bin\ant.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\tools\android.bat update project -n ButtonDemo -t android-17 -p d:\src");
    pcmd.StandardInput.WriteLine("");
    pcmd.StandardInput.Write("D:\apktools\apache-ant-1.9.1\bin\ant.bat debug");
    pcmd.StandardInput.WriteLine("");
    pcmd.StandardInput.Write("D:\apktools\apache-ant-1.9.1\bin\ant.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\tools\android.bat update project -n ButtonDemo -t android-17 -p d:\src > {log}
call D:\apktools\apache-ant-1.9.1\bin\ant.bat debug >> {log}
call D:\apktools\apache-ant-1.9.1\bin\ant.bat release >> {log}

由于不能用RedirectStandardOutput=true来获取输出信息,所以这里我用了dos命令 >> {log}来输出。
 
    最终的打包代码如下:
private bool Package()
{
    //先删除编译后的文件,执行完批处理后,通过判断文件存在与否来确定打包是否成功
    string releaseFile = "d:\src\ButtonDemo-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:\src\AndroidManifest.xml");
}

 
 
 
 
 
    

C#实现APK自动打包的更多相关文章

  1. Unity自动打包Apk

    unity打包apk相对来说比较容易,相信出过的人都明白,出包过程,没有大的难度,一步一操作,一步一等待,繁琐耗时,不懂的人又代替不了.这时候需求就来了,如何简单的一键打包搞定,这个就稍微有点难度,当 ...

  2. unity3d在菜单栏,一键设置Player setting及自动打包并设置apk的存储位置

    项目进行中,领导要求能够进行一键设置Player settings及自动打包并设置apk的位置,所以自己就上网搜索了很多大神的文章.最后是完成了领导需要的功能,在这里记录并分享一下(此项指针对安卓ap ...

  3. Android Studio Gradle 多渠道自动打包,动态修改HostUrl,签名apk,混淆配置详解

    文/ skay csdn博客:http://blog.csdn.net/sk719887916/article/details/40541163 最近遇到项目从Eclispe迁移到Android st ...

  4. Gradle实现自动打包,签名,自定义apk文件名

    Gradle实现自动打包,签名,自定义apk文件名 什么是签名,签名有什么用 Android APP都需要我们用一个证书对应用进行数字签名,不然的话是无法安装到Android手机上的,平时我们调试运行 ...

  5. 建立apk定时自动打包系统第二篇——自动上传文件

    在<建立apk定时自动打包系统第一篇——Ant多渠道打包并指定打包目录和打包日期>这篇文章中介绍多渠道打包的流程.很多时候我们需要将打包好的apk上传到ftp中,这时候我可以修改custo ...

  6. 建立apk定时自动打包系统第三篇——代码自动更新、APP自动打包系统

    我们的思路是每天下班后团队各成员在指定的时间(例如下午18:30)之前把各自的代码上传到SVN,然后服务器在指定的时间(例如下午18:30)更新代码.执行ant 打包命令.最后将apk包存放在指定目录 ...

  7. Android ant自动打包脚本:自动替换友盟渠道、版本号、包名

    本文最后修改时间:2014-3-10 Android项目开发时,给公司人员安装,频繁升级,版本号总需要改,太麻烦,跟着时间变,自动升级才方便. Android项目开发新版时,手机上可能要装两个版本,一 ...

  8. [原] Jenkins Android 自动打包配置

    一.Jenkins自动打包配置 目标:1. 自动打包:2. 自动上传:3. 友好下载 1. Jenkins简介 Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作. 减少重复劳 ...

  9. ANT自动打包U3D安卓项目研究笔记

    概述 因项目使用Atlassian Stash作为项目源码管理端,且其支持Ant命令自动编译,可使其根据最新的代码自动打包,故产生该研究Ant打包的任务.在此将研究过程及一些相关知识整理记录在此. 本 ...

随机推荐

  1. 【Spring】如何在单个Boot应用中配置多数据库?

    原创 BOOT 为什么需要多数据库? 默认情况下,Spring Boot使用的是单数据库配置(通过spring.datasource.*配置具体数据库连接信息).对于绝大多数Spring Boot应用 ...

  2. Eliza Doolittle lyrics Big City

    Eliza Doolittle lyrics  Big City 歌词很好,现在还没有,以后添加进来.

  3. 【转载】git/github初级运用自如

    之前了解过github,并在上面看了一些项目的源代码,于是自己也在github上创建了账户,希望以后有机会也把自己的项目托管在上面去.但是前提你要先了解git/github,下面的内容是从我的好基友虫 ...

  4. 常用的coco2d-x游戏开发工具(转)

    物理编辑工具Physics Editing ToolsMekanimo 网址:http://www.mekanimo.net/PhysicsBench 网址:http://www.cocos2d-ip ...

  5. MacOS安装phpMyAdmin几点问题

    1. 登录时出现“#2002 无法登录 MySQL 服务器”. 原因: phpMyAdmin为PHP编写,MacOS默认安装的php配置,设置mysql监听socket默认为/var/mysql/my ...

  6. POJ1037A decorative fence(好dp)

    1037 带点组合的东西吧 黑书P257 其实我没看懂它写的嘛玩意儿 这题还是挺不错的 一个模糊的思路可能会好想一些 就是大体的递推方程 dp1[][]表示降序 dp2[][]表示升序 数组的含义为长 ...

  7. poj 2828 Buy Tickets (线段树)

    题目:http://poj.org/problem?id=2828 题意:有n个人插队,给定插队的先后顺序和插在哪个位置还有每个人的val,求插队结束后队伍各位置的val. 线段树里比较简单的题目了, ...

  8. hdu 4937 Lucky Number

    虽然算法清晰的不能再清晰,但是实现总是边角料错这错那. 题目大意: 给出n,找出一些进制,使得n在该进制下仅为3,4,5,6表示 解题思路: 首先,4-10000进制直接枚举计算出每一位 此外,最多只 ...

  9. POJ 1577 Falling Leaves

    题意:给出一些字符串,从上到下的建树,输出其前序遍历 像前面那一题一样,先建树,然后再递归前序遍历 不过想像上一题那样用数组建树,建树和上题一样的办法,可是应该怎么输出前序遍历呢= = 还是看的题解= ...

  10. asp.net获取当前页面源码并生成静态页面

    StringWriter stringWriter = new StringWriter(); HtmlTextWriter htmlWriter = new HtmlTextWriter(strin ...