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 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");
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值