android_apk 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "android_apk"
8
- s.version = "0.5.0"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kyosuke INOUE"]
12
- s.date = "2012-07-31"
12
+ s.date = "2012-08-14"
13
13
  s.description = "This library can analyze Android APK application package. You can get any information of android apk file."
14
14
  s.email = "kyoro@hakamastyle.net"
15
15
  s.extra_rdoc_files = [
@@ -28,8 +28,9 @@ Gem::Specification.new do |s|
28
28
  "android_apk.gemspec",
29
29
  "lib/android_apk.rb",
30
30
  "spec/android_apk_spec.rb",
31
+ "spec/mock/BarcodeScanner4.2.apk",
31
32
  "spec/mock/dummy.apk",
32
- "spec/mock/vibee.apk",
33
+ "spec/mock/sample.apk",
33
34
  "spec/spec_helper.rb"
34
35
  ]
35
36
  s.homepage = "http://github.com/kyoro/android_apk"
@@ -1,42 +1,104 @@
1
1
  require "tmpdir"
2
2
  require "pp"
3
3
  class AndroidApk
4
- attr_accessor :results,:label,:icon,:package_name,:version_code, :version_name, :filepath
4
+ attr_accessor :results,:label,:labels,:icon,:icons,:package_name,:version_code,:version_name,:sdk_version,:target_sdk_version,:filepath
5
5
  def self.analyze(filepath)
6
6
  return nil unless File.exist?(filepath)
7
7
  apk = AndroidApk.new
8
- command = "aapt dump badging " + filepath + " 2>&1"
8
+ command = "aapt dump badging '" + filepath + "' 2>&1"
9
9
  results = `#{command}`
10
- if results.index("ERROR: dump failed")
10
+ if $?.exitstatus != 0 or results.index("ERROR: dump failed")
11
11
  return nil
12
12
  end
13
13
  apk.filepath = filepath
14
14
  apk.results = results
15
- results.split("\n").each do |line|
16
- info = line.split("\s")
17
- # application info
18
- if info[0] == "application:"
19
- apk.label = info[1].split("'")[1]
20
- apk.icon = info[2].split("'")[1]
21
- end
22
- #package
23
- if info[0] == "package:"
24
- apk.package_name = info[1].split("'")[1]
25
- apk.version_code = info[2].split("'")[1]
26
- apk.version_name = info[3].split("'")[1]
27
- end
15
+ vars = _parse_aapt(results)
16
+
17
+ # application info
18
+ apk.label, apk.icon =
19
+ vars['application'].values_at('label', 'icon')
20
+
21
+ # package
22
+ apk.package_name, apk.version_code, apk.version_name =
23
+ vars['package'].values_at('name', 'versionCode', 'versionName')
24
+
25
+ # platforms
26
+ apk.sdk_version = vars['sdkVersion']
27
+ apk.target_sdk_version = vars['targetSdkVersion']
28
+
29
+ # icons and labels
30
+ apk.icons = Hash.new
31
+ apk.labels = Hash.new
32
+ vars.each_key do |k|
33
+ k =~ /^application-icon-(\d+)$/ && apk.icons[$1.to_i] = vars[k]
34
+ k =~ /^application-label-(\S+)$/ && apk.labels[$1] = vars[k]
28
35
  end
36
+
29
37
  return apk
30
38
  end
31
39
 
32
- def icon_file
40
+ def icon_file(dpi = nil)
41
+ icon = dpi ? self.icons[dpi.to_i] : self.icon
42
+ return nil unless icon
33
43
  Dir.mktmpdir do |dir|
34
- command = sprintf("unzip %s %s -d %s 2>&1",self.filepath,self.icon,dir)
44
+ command = sprintf("unzip '%s' '%s' -d '%s' 2>&1",self.filepath,icon,dir)
35
45
  results = `#{command}`
36
- path = dir + "/" + self.icon
37
- return nil unless File.exist?(path)
46
+ path = dir + "/" + icon
47
+ return nil unless File.exist?(path)
38
48
  return File.new(path,'r')
39
49
  end
40
50
  end
41
51
 
52
+ def signature
53
+ command = sprintf("unzip -p '%s' META-INF/*.RSA | keytool -printcert | grep SHA1: 2>&1", self.filepath)
54
+ results = `#{command}`
55
+ return nil if $?.exitstatus != 0 || results.nil? || !results.index('SHA1:')
56
+ val = results.scan(/(?:[0-9A-Z]{2}:?){20}/)
57
+ return nil if val.nil? || val.length != 1
58
+ return val[0].gsub(/:/, "").downcase
59
+ end
60
+
61
+ def self._parse_values(str)
62
+ return nil if str.nil?
63
+ if str.index("='")
64
+ # key-value hash
65
+ vars = Hash[str.scan(/(\S+)='((?:\\'|[^'])*)'/)]
66
+ vars.each_value {|v| v.gsub(/\\'/, "'")}
67
+ else
68
+ # values array
69
+ vars = str.scan(/'((?:\\'|[^'])*)'/).map{|v| v[0].gsub(/\\'/, "'")}
70
+ end
71
+ return vars
72
+ end
73
+
74
+ def self._parse_line(line)
75
+ return nil if line.nil?
76
+ info = line.split(":", 2)
77
+ return info[0], _parse_values( info[1] )
78
+ end
79
+
80
+ def self._parse_aapt(results)
81
+ vars = Hash.new
82
+ results.split("\n").each do |line|
83
+ key, value = _parse_line(line)
84
+ next if key.nil?
85
+ if vars.key?(key)
86
+ if (vars[key].is_a?(Hash) and value.is_a?(Hash))
87
+ vars[key].merge(value)
88
+ else
89
+ vars[key] = [vars[key]] unless (vars[key].is_a?(Array))
90
+ if (value.is_a?(Array))
91
+ vars[key].concat(value)
92
+ else
93
+ vars[key].push(value)
94
+ end
95
+ end
96
+ else
97
+ vars[key] = value.nil? ? nil :
98
+ (value.is_a?(Hash) ? value :
99
+ (value.length > 1 ? value : value[0]))
100
+ end
101
+ end
102
+ return vars
103
+ end
42
104
  end
@@ -1,12 +1,17 @@
1
+ # encoding: utf-8
1
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
3
  require "pp"
3
4
 
4
5
  describe "AndroidApk" do
5
6
  apk = nil
6
- sample_file_path = File.dirname(__FILE__) + "/mock/vibee.apk"
7
+ apk2 = nil
8
+ sample_file_path = File.dirname(__FILE__) + "/mock/sample.apk"
9
+ sample2_file_path = File.dirname(__FILE__) + "/mock/BarcodeScanner4.2.apk"
7
10
  dummy_file_path = File.dirname(__FILE__) + "/mock/dummy.apk"
11
+
8
12
  it "Sample apk file exist" do
9
13
  File.exist?(sample_file_path).should == true
14
+ File.exist?(sample2_file_path).should == true
10
15
  end
11
16
 
12
17
  it "Library can not read apk file" do
@@ -22,18 +27,55 @@ describe "AndroidApk" do
22
27
  it "Library can read apk file" do
23
28
  apk = AndroidApk.analyze(sample_file_path)
24
29
  apk.should_not == nil
30
+ apk2 = AndroidApk.analyze(sample2_file_path)
31
+ apk2.should_not == nil
25
32
  end
26
33
 
27
34
  it "Can read apk information" do
28
- apk.icon.should == "res/drawable/appicon.png"
29
- apk.label.should == "vibee"
30
- apk.package_name.should == "net.hakamastyle.app.vibee"
35
+ apk.icon.should == "res/drawable-mdpi/ic_launcher.png"
36
+ apk.label.should == "sample"
37
+ apk.package_name.should == "com.example.sample"
31
38
  apk.version_code.should == "1"
32
- apk.version_name.should == "1"
39
+ apk.version_name.should == "1.0"
40
+ apk.sdk_version.should == "7"
41
+ apk.target_sdk_version.should == "15"
42
+ apk.labels.length.should == 1
43
+ apk.labels['ja'].should == 'サンプル'
44
+ end
45
+
46
+ it "Can read signature" do
47
+ apk.signature.should == "c1f285f69cc02a397135ed182aa79af53d5d20a1"
33
48
  end
34
49
 
35
50
  it "Icon file unzip" do
51
+ apk.icons.length.should == 3
36
52
  apk.icon_file.should_not == nil
53
+ apk.icon_file(apk.icons.keys[0]).should_not == nil
54
+ end
55
+
56
+ it "Can read apk information 2" do
57
+ apk2.icon.should == "res/drawable/launcher_icon.png"
58
+ apk2.label.should == "Barcode Scanner"
59
+ apk2.package_name.should == "com.google.zxing.client.android"
60
+ apk2.version_code.should == "84"
61
+ apk2.version_name.should == "4.2"
62
+ apk2.sdk_version.should == "7"
63
+ apk2.target_sdk_version.should == "7"
64
+ apk2.labels.length.should == 29
65
+ apk2.labels['ja'].should == 'QRコードスキャナー'
66
+ end
67
+
68
+ it "Icon file unzip 2" do
69
+ apk2.icons.length.should == 3
70
+ apk2.icon_file.should_not == nil
71
+ apk2.icon_file(120).should_not == nil
72
+ apk2.icon_file("120").should_not == nil
73
+ apk2.icon_file(160).should_not == nil
74
+ apk2.icon_file(240).should_not == nil
75
+ end
76
+
77
+ it "Can read signature 2" do
78
+ apk2.signature.should == "e460df681d330f93f92e712cd79985d99379f5e0"
37
79
  end
38
80
 
39
81
  end
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: android_apk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-31 00:00:00.000000000Z
12
+ date: 2012-08-14 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70149249299080 !ruby/object:Gem::Requirement
16
+ requirement: &70291512279780 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.8.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70149249299080
24
+ version_requirements: *70291512279780
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rdoc
27
- requirement: &70149249298120 !ruby/object:Gem::Requirement
27
+ requirement: &70291512279240 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.12'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70149249298120
35
+ version_requirements: *70291512279240
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &70149249297580 !ruby/object:Gem::Requirement
38
+ requirement: &70291512278680 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.0.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70149249297580
46
+ version_requirements: *70291512278680
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: jeweler
49
- requirement: &70149249296900 !ruby/object:Gem::Requirement
49
+ requirement: &70291512277920 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.8.4
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70149249296900
57
+ version_requirements: *70291512277920
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: simplecov
60
- requirement: &70149249296040 !ruby/object:Gem::Requirement
60
+ requirement: &70291512234160 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70149249296040
68
+ version_requirements: *70291512234160
69
69
  description: This library can analyze Android APK application package. You can get
70
70
  any information of android apk file.
71
71
  email: kyoro@hakamastyle.net
@@ -86,8 +86,9 @@ files:
86
86
  - android_apk.gemspec
87
87
  - lib/android_apk.rb
88
88
  - spec/android_apk_spec.rb
89
+ - spec/mock/BarcodeScanner4.2.apk
89
90
  - spec/mock/dummy.apk
90
- - spec/mock/vibee.apk
91
+ - spec/mock/sample.apk
91
92
  - spec/spec_helper.rb
92
93
  homepage: http://github.com/kyoro/android_apk
93
94
  licenses:
@@ -104,7 +105,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
105
  version: '0'
105
106
  segments:
106
107
  - 0
107
- hash: -4141399800137927728
108
+ hash: -4046564930370041646
108
109
  required_rubygems_version: !ruby/object:Gem::Requirement
109
110
  none: false
110
111
  requirements:
Binary file