Class: AndroidApk

Inherits:
Object
  • Object
show all
Defined in:
lib/android_apk.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#filepathObject

Returns the value of attribute filepath.



4
5
6
# File 'lib/android_apk.rb', line 4

def filepath
  @filepath
end

#iconObject

Returns the value of attribute icon.



4
5
6
# File 'lib/android_apk.rb', line 4

def icon
  @icon
end

#iconsObject

Returns the value of attribute icons.



4
5
6
# File 'lib/android_apk.rb', line 4

def icons
  @icons
end

#labelObject

Returns the value of attribute label.



4
5
6
# File 'lib/android_apk.rb', line 4

def label
  @label
end

#labelsObject

Returns the value of attribute labels.



4
5
6
# File 'lib/android_apk.rb', line 4

def labels
  @labels
end

#package_nameObject

Returns the value of attribute package_name.



4
5
6
# File 'lib/android_apk.rb', line 4

def package_name
  @package_name
end

#resultsObject

Returns the value of attribute results.



4
5
6
# File 'lib/android_apk.rb', line 4

def results
  @results
end

#sdk_versionObject

Returns the value of attribute sdk_version.



4
5
6
# File 'lib/android_apk.rb', line 4

def sdk_version
  @sdk_version
end

#target_sdk_versionObject

Returns the value of attribute target_sdk_version.



4
5
6
# File 'lib/android_apk.rb', line 4

def target_sdk_version
  @target_sdk_version
end

#version_codeObject

Returns the value of attribute version_code.



4
5
6
# File 'lib/android_apk.rb', line 4

def version_code
  @version_code
end

#version_nameObject

Returns the value of attribute version_name.



4
5
6
# File 'lib/android_apk.rb', line 4

def version_name
  @version_name
end

Class Method Details

._parse_aapt(results) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/android_apk.rb', line 80

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)
      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) ⇒ Object



74
75
76
77
78
# File 'lib/android_apk.rb', line 74

def self._parse_line(line)
  return nil if line.nil?
  info = line.split(":", 2)
  return info[0], _parse_values( info[1] )
end

._parse_values(str) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/android_apk.rb', line 61

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

.analyze(filepath) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/android_apk.rb', line 5

def self.analyze(filepath)
  return nil unless File.exist?(filepath)
  apk = AndroidApk.new
  command = "aapt dump badging '" + filepath + "' 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, apk.icon =
    vars['application'].values_at('label', '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

Instance Method Details

#icon_file(dpi = nil) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/android_apk.rb', line 40

def icon_file(dpi = nil)
  icon = dpi ? self.icons[dpi.to_i] : self.icon
  return nil if icon.empty?
  Dir.mktmpdir do |dir|
    command = sprintf("unzip '%s' '%s' -d '%s' 2>&1",self.filepath,icon,dir)
    results = `#{command}`
    path =  dir + "/" + icon 
    return nil unless File.exist?(path)
    return File.new(path,'r')
  end
end

#signatureObject



52
53
54
55
56
57
58
59
# File 'lib/android_apk.rb', line 52

def signature
  command = sprintf("unzip -p '%s' META-INF/*.RSA | keytool -printcert | grep SHA1: 2>&1", self.filepath)
  results = `#{command}`
  return nil if $?.exitstatus != 0 || results.nil? || !results.index('SHA1:')
  val = results.scan(/(?:[0-9A-Z]{2}:?){20}/)
  return nil if val.nil? || val.length != 1
  return val[0].gsub(/:/, "").downcase
end