code: async function extractApkInfoWithApkanalyzer (localApk, apkanalyzerPath) {
    const args = ['-h', 'manifest', 'print', localApk];
    log.debug(`Starting '${apkanalyzerPath}' with args ${JSON.stringify(args)}`);
    const manifestXml = (await exec(apkanalyzerPath, args, {
      shell: true,
      cwd: path.dirname(apkanalyzerPath)
    })).stdout;
    const doc = new xmldom.DOMParser().parseFromString(manifestXml);
    const apkPackageAttribute = xpath.select1('//manifest/@package', doc);
    if (!apkPackageAttribute) {
      throw new Error(`Cannot parse package name from ${manifestXml}`);
    }
    const apkPackage = apkPackageAttribute.value;
    // Look for activity or activity-alias with
    // action == android.intent.action.MAIN and
    // category == android.intent.category.LAUNCHER
    // descendants
    const apkActivityAttribute = xpath.select1(
      "//application/*[starts-with(name(), 'activity') " +
      "and .//action[@*[local-name()='name' and .='android.intent.action.MAIN']] " +
      "and .//category[@*[local-name()='name' and .='android.intent.category.LAUNCHER']]]" +
      "/@*[local-name()='name']", doc);
    if (!apkActivityAttribute) {
      throw new Error(`Cannot parse main activity name from ${manifestXml}`);
    }
    const apkActivity = apkActivityAttribute.value;
    return {apkPackage, apkActivity};
  }
docs: Extract package and main activity name from application manifest using
  apkanalyzer tool.
  
  @param {string} localApk - The full path to application package.
  @param {string} apkanalyzerPath - The full path to apkanalyzer tool.
  @return {APKInfo} The parsed application info.
  @throws {Error} If there was an error while getting the data from the given
  application package or if the tool itself
  is not present on the local file system.