class AndroidApk
Constants
- NOT_ALLOW_DUPLICATE_TAG_NAMES
Attributes
filepath[RW]
icon[RW]
icons[RW]
label[RW]
labels[RW]
package_name[RW]
results[RW]
sdk_version[RW]
target_sdk_version[RW]
version_code[RW]
version_name[RW]
Public Class Methods
_parse_aapt(results)
click to toggle source
# File lib/android_apk.rb, line 124 def self._parse_aapt(results) vars = Hash.new results.split("\n").each do |line| key, value = _parse_line(line) next if key.nil? if vars.key?(key) && allow_duplicate?(key) if (vars[key].is_a?(Hash) and value.is_a?(Hash)) vars[key].merge(value) else vars[key] = [vars[key]] unless (vars[key].is_a?(Array)) if (value.is_a?(Array)) vars[key].concat(value) else vars[key].push(value) end end else vars[key] = value.nil? ? nil : (value.is_a?(Hash) ? value : (value.length > 1 ? value : value[0])) end end return vars end
_parse_line(line)
click to toggle source
# File lib/android_apk.rb, line 112 def self._parse_line(line) return nil if line.nil? info = line.split(":", 2) values = if info[0].start_with?('application-label') _parse_values_workaround info[1] else _parse_values info[1] end return info[0], values end
_parse_values(str)
click to toggle source
# File lib/android_apk.rb, line 99 def self._parse_values(str) return nil if str.nil? if str.index("='") # key-value hash vars = Hash[str.scan(/(\S+)='((?:\\'|[^'])*)'/)] vars.each_value {|v| v.gsub(/\\'/, "'")} else # values array vars = str.scan(/'((?:\\'|[^'])*)'/).map{|v| v[0].gsub(/\\'/, "'")} end return vars end
_parse_values_workaround(str)
click to toggle source
workaround for code.google.com/p/android/issues/detail?id=160847
# File lib/android_apk.rb, line 94 def self._parse_values_workaround(str) return nil if str.nil? str.scan(/^'(.+)'$/).map{|v| v[0].gsub(/\\'/, "'")} end
allow_duplicate?(key)
click to toggle source
# File lib/android_apk.rb, line 149 def self.allow_duplicate?(key) raise AndroidManifestValidateError, "Duplication of #{key} tag is not allowed" if NOT_ALLOW_DUPLICATE_TAG_NAMES.include?(key) true end
analyze(filepath)
click to toggle source
# File lib/android_apk.rb, line 12 def self.analyze(filepath) return nil unless File.exist?(filepath) apk = AndroidApk.new command = "aapt dump badging #{filepath.shellescape} 2>&1" results = `#{command}` if $?.exitstatus != 0 or results.index("ERROR: dump failed") return nil end apk.filepath = filepath apk.results = results vars = _parse_aapt(results) # application info apk.label = vars['application-label'] apk.icon = vars['application']['icon'] # package apk.package_name, apk.version_code, apk.version_name = vars['package'].values_at('name', 'versionCode', 'versionName') # platforms apk.sdk_version = vars['sdkVersion'] apk.target_sdk_version = vars['targetSdkVersion'] # icons and labels apk.icons = Hash.new apk.labels = Hash.new vars.each_key do |k| k =~ /^application-icon-(\d+)$/ && apk.icons[$1.to_i] = vars[k] k =~ /^application-label-(\S+)$/ && apk.labels[$1] = vars[k] end return apk end
Public Instance Methods
dpi_str(dpi)
click to toggle source
# File lib/android_apk.rb, line 65 def dpi_str(dpi) case dpi.to_i when 120 'ldpi' when 160 'mdpi' when 240 'hdpi' when 320 'xhdpi' when 480 'xxhdpi' when 640 'xxxhdpi' else 'xxxhdpi' end end
icon_file(dpi = nil, want_png = false)
click to toggle source
# File lib/android_apk.rb, line 47 def icon_file(dpi = nil, want_png = false) icon = dpi ? self.icons[dpi.to_i] : self.icon return nil if icon.empty? if want_png && icon.end_with?('.xml') dpis = dpi_str(dpi) icon.gsub! %r{res/(drawable|mipmap)-anydpi-(?:v\d+)/([^/]+)\.xml}, "res/\\1-#{dpis}-v4/\\2.png" end Dir.mktmpdir do |dir| command = "unzip #{self.filepath.shellescape} #{icon.shellescape} -d #{dir.shellescape} 2>&1" results = `#{command}` path = dir + "/" + icon return nil unless File.exist?(path) return File.new(path,'r') end end
signature()
click to toggle source
# File lib/android_apk.rb, line 84 def signature command = "unzip -p #{self.filepath.shellescape} META-INF/*.RSA META-INF/*.DSA | keytool -printcert | grep SHA1:" output, _, status = Open3.capture3(command) return if status != 0 || output.nil? || !output.index('SHA1:') val = output.scan(/(?:[0-9A-Z]{2}:?){20}/) return nil if val.nil? || val.length != 1 return val[0].gsub(/:/, "").downcase end