android_apk 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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