private void buildApk() throws Exception {
    // Do NOT use ApkBuilder's embedded JarSigner
    PrivateKey privateKey = null;
    X509Certificate x509Cert = null;

    ApkBuilder apkbuilder =
        new ApkBuilder(
            S.apkUnsigned, S.ap_Resources, S.dexClasses, privateKey, x509Cert, System.out);

    if (setProgress(65, R.string.addLibs)) {
      return;
    }
    apkbuilder.addNativeLibraries(S.dirLibs);

    int percent = 65;

    for (File jarLib : S.dirLibs.listFiles()) {

      // skip native libs in sub directories
      if (!jarLib.isFile() || !jarLib.getName().endsWith(".jar")) {
        continue;
      }
      apkbuilder.addResourcesFromJar(jarLib);

      if (setProgress(++percent)) {
        return;
      }
    }

    if (setProgress(75, R.string.zipAssets)) {
      return;
    }
    Util.zip(S.dirSrc, S.zipSrc);
    Util.zip(S.dirRes, S.zipRes);
    Util.zip(S.dirLibs, S.zipLibs);
    Util.zip(S.dirDexedLibs, S.zipDexedLibs);

    if (setProgress(80, R.string.addAssets)) {
      return;
    }
    String strAssets = S.dirAssets.getName() + File.separator;
    apkbuilder.addFile(S.xmlMan, strAssets + S.xmlMan.getName());
    apkbuilder.addFile(S.zipSrc, strAssets + S.zipSrc.getName());
    apkbuilder.addFile(S.zipRes, strAssets + S.zipRes.getName());
    apkbuilder.addFile(S.zipLibs, strAssets + S.zipLibs.getName());
    apkbuilder.addFile(S.zipDexedLibs, strAssets + S.zipDexedLibs.getName());

    apkbuilder.setDebugMode(true);
    apkbuilder.sealApk();
  }