";h=l?b(c).prependTo(g):b(c).appendTo(g),k=h.height(),i=h.find(".refresh-icon"),j=h.find(".refresh-label")},o=function(b){return a.Scroll(b.selector,{topOffset:l?k:0,bounce:!0,onScrollMove:function(){this.y>b.minPullHeight&&l&&!i.hasClass(b.onReleaseIcon)?(i.addClass(b.onReleaseIcon),j.html(b.releaseText),this.minScrollY=0):this.ythis.maxScrollY+b.minPullHeight&&!l&&i.hasClass(b.onReleaseIcon)&&(i.removeClass(b.onReleaseIcon),j.html(b.pullText),this.maxScrollY=k)},onScrollEnd:function(){if(i.hasClass(b.onReleaseIcon)){i.removeClass(b.onReleaseIcon).removeClass(b.onPullIcon).addClass(b.onRefreshIcon),j.html(b.refreshText);var a=this;setTimeout(function(){b.callback.call(a)},1)}},onRefresh:function(){i.removeClass(b.onRefreshIcon).addClass(b.onPullIcon),j.html(b.pullText)}})};return n(m),f=o(m)}var d={},e=1;a.Refresh=function(a,f,g){var h,i;if(h=a.selector?b(a.selector):b(a),i=h.data("_jrefresh_"),i&&d[i])return d[i];i="_jrefresh_"+e++,h.data("_jrefresh_",i);var j=new c(a,f,g);return d[i]={scroller:j.scroller,destroy:function(){delete d[i],j.destroy(),b(".refresh-container",a).remove()}}}}(Jingle,Zepto);
--------------------------------------------------------------------------------
/assets/www/js/lib/pgPlugin.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | if(!window.plugins) {
3 | window.plugins = {};
4 | }
5 | /**
6 | * 条码扫描
7 | * @type {Object}
8 | */
9 | window.plugins.barcodeScanner = {
10 | scan : function(mode,win,err){
11 | cordova.exec(win, err, "BarcodeScanner", "scan", [mode]);
12 | }
13 | }
14 | /**
15 | * 对key进行签名
16 | * @type {Object}
17 | */
18 | window.plugins.eoeSign = {
19 | get : function(key,win,err){
20 | cordova.exec(win, err, "Sign", "get", [key]);
21 | }
22 | }
23 | })();
24 |
--------------------------------------------------------------------------------
/assets/www/js/lib/template.min.js:
--------------------------------------------------------------------------------
1 | /*!artTemplate - Template Engine*/var template=function(a,b){return template["object"==typeof b?"render":"compile"].apply(template,arguments)};(function(a,b){"use strict";a.version="2.0.1",a.openTag="<%",a.closeTag="%>",a.isEscape=!0,a.isCompress=!1,a.parser=null,a.render=function(a,b){var c=d(a);return void 0===c?e({id:a,name:"Render Error",message:"No Template"}):c(b)},a.compile=function(b,d){function l(c){try{return new j(c)+""}catch(f){return h?(f.id=b||d,f.name="Render Error",f.source=d,e(f)):a.compile(b,d,!0)(c)}}var g=arguments,h=g[2],i="anonymous";"string"!=typeof d&&(h=g[1],d=g[0],b=i);try{var j=f(d,h)}catch(k){return k.id=b||d,k.name="Syntax Error",e(k)}return l.prototype=j.prototype,l.toString=function(){return""+j},b!==i&&(c[b]=l),l},a.helper=function(b,c){a.prototype[b]=c},a.onerror=function(a){var c="[template]:\n"+a.id+"\n\n[name]:\n"+a.name;a.message&&(c+="\n\n[message]:\n"+a.message),a.line&&(c+="\n\n[line]:\n"+a.line,c+="\n\n[source]:\n"+a.source.split(/\n/)[a.line-1].replace(/^[\s\t]+/,"")),a.temp&&(c+="\n\n[temp]:\n"+a.temp),b.console&&console.error(c)};var c={},d=function(d){var e=c[d];if(void 0===e&&"document"in b){var f=document.getElementById(d);if(f){var g=f.value||f.innerHTML;return a.compile(d,g.replace(/^\s*|\s*$/g,""))}}else if(c.hasOwnProperty(d))return e},e=function(b){function c(){return c+""}return a.onerror(b),c.toString=function(){return"{Template Error}"},c},f=function(){a.prototype={$render:a.render,$escape:function(a){return"string"==typeof a?a.replace(/&(?![\w#]+;)|[<>"']/g,function(a){return{"<":"<",">":">",'"':""","'":"'","&":"&"}[a]}):a},$string:function(a){return"string"==typeof a||"number"==typeof a?a:"function"==typeof a?a():""}};var b=Array.prototype.forEach||function(a,b){for(var c=this.length>>>0,d=0;c>d;d++)d in this&&a.call(b,this[d],d,this)},c=function(a,c){b.call(a,c)},d="break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined",e=/\/\*(?:.|\n)*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|'[^']*'|"[^"]*"|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g,f=/[^\w$]+/g,g=RegExp(["\\b"+d.replace(/,/g,"\\b|\\b")+"\\b"].join("|"),"g"),h=/\b\d[^,]*/g,i=/^,+|,+$/g,j=function(a){return a=a.replace(e,"").replace(f,",").replace(g,"").replace(h,"").replace(i,""),a=a?a.split(/,+/):[]};return function(b,d){function w(b){return k+=b.split(/\n/).length-1,a.isCompress&&(b=b.replace(/[\n\r\t\s]+/g," ")),b=b.replace(/('|\\)/g,"\\$1").replace(/\r/g,"\\r").replace(/\n/g,"\\n"),b=q[1]+"'"+b+"'"+q[2],b+"\n"}function x(b){var c=k;if(g?b=g(b):d&&(b=b.replace(/\n/g,function(){return k++,"$line="+k+";"})),0===b.indexOf("=")){var e=0!==b.indexOf("==");if(b=b.replace(/^=*|[\s;]*$/g,""),e&&a.isEscape){var f=b.replace(/\s*\([^\)]+\)/,"");m.hasOwnProperty(f)||/^(include|print)$/.test(f)||(b="$escape($string("+b+"))")}else b="$string("+b+")";b=q[1]+b+q[2]}return d&&(b="$line="+c+";"+b),y(b),b+"\n"}function y(a){a=j(a),c(a,function(a){l.hasOwnProperty(a)||(z(a),l[a]=!0)})}function z(a){var b;"print"===a?b=s:"include"===a?(n.$render=m.$render,b=t):(b="$data."+a,m.hasOwnProperty(a)&&(n[a]=m[a],b=0===a.indexOf("$")?"$helpers."+a:b+"===undefined?$helpers."+a+":"+b)),o+=a+"="+b+","}var e=a.openTag,f=a.closeTag,g=a.parser,h=b,i="",k=1,l={$data:!0,$helpers:!0,$out:!0,$line:!0},m=a.prototype,n={},o="var $helpers=this,"+(d?"$line=0,":""),p="".trim,q=p?["$out='';","$out+=",";","$out"]:["$out=[];","$out.push(",");","$out.join('')"],r=p?"if(content!==undefined){$out+=content;return content}":"$out.push(content);",s="function(content){"+r+"}",t="function(id,data){if(data===undefined){data=$data}var content=$helpers.$render(id,data);"+r+"}";c(h.split(e),function(a){a=a.split(f);var c=a[0],d=a[1];1===a.length?i+=w(c):(i+=x(c),d&&(i+=w(d)))}),h=i,d&&(h="try{"+h+"}catch(e){"+"e.line=$line;"+"throw e"+"}"),h="'use strict';"+o+q[0]+h+"return new String("+q[3]+")";try{var u=Function("$data",h);return u.prototype=n,u}catch(v){throw v.temp="function anonymous($data) {"+h+"}",v}}}()})(template,this),"function"==typeof define?define(function(a,b,c){c.exports=template}):"undefined"!=typeof exports&&(module.exports=template);(function(exports){exports.openTag="{";exports.closeTag="}";exports.parser=function(code){code=code.replace(/^\s/,"");var args=code.split(" ");var key=args.shift();var keywords=exports.keywords;var fuc=keywords[key];if(fuc&&keywords.hasOwnProperty(key)){args=args.join(" ");code=fuc.call(code,args)}else{if(exports.prototype.hasOwnProperty(key)){args=args.join(",");code="=="+key+"("+args+");"}else{code=code.replace(/[\s;]*$/,"");code="="+code}}return code};exports.keywords={"if":function(code){return"if("+code+"){"},"else":function(code){code=code.split(" ");if(code.shift()==="if"){code=" if("+code.join(" ")+")"}else{code=""}return"}else"+code+"{"},"/if":function(){return"}"},"each":function(code){code=code.split(" ");var object=code[0]||"$data";var as=code[1]||"as";var value=code[2]||"$value";var index=code[3]||"$index";var args=value+","+index;if(as!=="as"){object="[]"}return"$each("+object+",function("+args+"){"},"/each":function(){return"});"},"echo":function(code){return"print("+code+");"},"include":function(code){code=code.split(" ");var id=code[0];var data=code[1];var args=id+(data?(","+data):"");return"include("+args+");"}};exports.helper("$each",function(data,callback){var isArray=Array.isArray||function(obj){return Object.prototype.toString.call(obj)==="[object Array]"};if(isArray(data)){for(var i=0,len=data.length;i 1) {
31 | if (mappedevent) {
32 | callback = fakeTouches(type, callback, context);
33 | }
34 |
35 | result.push(callback);
36 | }
37 |
38 |
39 | return result;
40 | }
41 | function fakeTouches(type, callback, context) {
42 | // wrap the callback with a function that adds a fake
43 | // touches property to the event.
44 |
45 | return _fakeCallbacks[callback] = function (event) {
46 | if(event.liveFired)context = this;//if it is delegate event,change context to target element
47 | if (event.button) {
48 | return false;
49 | }
50 | event.touches = [{
51 | length: 1,// 1 mouse (finger)
52 | clientX: event.clientX,
53 | clientY: event.clienty,
54 | pageX: event.pageX,
55 | pageY: event.pageY,
56 | screenX: event.screenX,
57 | screenY: event.screenY,
58 | target: event.target
59 | }]
60 |
61 | event.touchtype = type;
62 |
63 | return callback.apply(context, [event]);
64 | }
65 | }
66 |
67 | var _bind = $.fn.bind;
68 | $.fn.bind = function(event, callback){
69 | return _bind.apply(this, touch2mouse(event, callback, this));
70 | };
71 | var _unbind = $.fn.unbind;
72 | $.fn.unbind = function(event, callback){
73 | if (!event) {
74 | _unbind.apply(this);
75 | return;
76 | }
77 | var result = _unbind.apply(this, touch2mouse(event).concat([_fakeCallbacks[callback]||callback]));
78 | delete(_fakeCallbacks[callback]);
79 | return result;
80 | };
81 | var _one = $.fn.one;
82 | $.fn.one = function(event, callback){
83 | return _one.apply(this, touch2mouse(event, callback, this));
84 | };
85 | var _delegate = $.fn.delegate;
86 | $.fn.delegate = function(selector, event, callback){
87 | return _delegate.apply(this, [selector].concat(touch2mouse(event, callback, this)));
88 | };
89 | var _undelegate = $.fn.undelegate;
90 | $.fn.undelegate = function(selector, event, callback){
91 | var result = _undelegate.apply(this, [selector].concat(touch2mouse(event), [_fakeCallbacks[callback]||callback]));
92 | delete(_fakeCallbacks[callback]);
93 | return result;
94 | };
95 | var _live = $.fn.live;
96 | $.fn.live = function(event, callback){
97 | return _live.apply(this, touch2mouse(event, callback, this));
98 | };
99 | var _die = $.fn.die;
100 | $.fn.die = function(event, callback){
101 | var result = _die.apply(this, touch2mouse(event).concat([_fakeCallbacks[callback]||callback]));
102 | delete(_fakeCallbacks[callback]);
103 | return result;
104 | };
105 | var _trigger = $.fn.trigger;
106 | $.fn.trigger = function(event, data){
107 | return _trigger.apply(this, touch2mouse(event).concat([data]));
108 | };
109 | var _triggerHandler = $.fn.triggerHandler;
110 | $.fn.triggerHandler = function(event, data){
111 | return _triggerHandler.apply(this, touch2mouse(event).concat([data]));
112 | };
113 | // var _on = $.fn.on;
114 | // $.fn.on = function(event, selector, callback){
115 | // return _on.apply(this, touch2mouse(event).concat([selector]));
116 | // }
117 | // var _off = $.fn.off;
118 |
119 | }
120 | })(Zepto);
--------------------------------------------------------------------------------
/gen/com/jingle/eoe/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package com.jingle.eoe;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/gen/com/jingle/eoe/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.jingle.eoe;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class color {
14 | public static final int possible_result_points=0x7f070002;
15 | public static final int result_view=0x7f070000;
16 | public static final int viewfinder_mask=0x7f070001;
17 | }
18 | public static final class drawable {
19 | public static final int barcode_back=0x7f020000;
20 | public static final int barcode_back_btn=0x7f020001;
21 | public static final int barcode_bg=0x7f020002;
22 | public static final int icon=0x7f020003;
23 | public static final int splashscreen=0x7f020004;
24 | }
25 | public static final class id {
26 | /** Messages IDs
27 | */
28 | public static final int auto_focus=0x7f060000;
29 | public static final int button_back=0x7f06000b;
30 | public static final int decode=0x7f060001;
31 | public static final int decode_failed=0x7f060002;
32 | public static final int decode_succeeded=0x7f060003;
33 | public static final int encode_failed=0x7f060004;
34 | public static final int encode_succeeded=0x7f060005;
35 | public static final int preview_view=0x7f060009;
36 | public static final int quit=0x7f060006;
37 | public static final int restart_preview=0x7f060007;
38 | public static final int return_scan_result=0x7f060008;
39 | public static final int textview_title=0x7f06000c;
40 | public static final int viewfinder_view=0x7f06000a;
41 | }
42 | public static final class layout {
43 | public static final int activity_capture=0x7f030000;
44 | }
45 | public static final class raw {
46 | public static final int beep=0x7f050000;
47 | }
48 | public static final class string {
49 | public static final int app_name=0x7f080003;
50 | public static final int scan_back=0x7f080001;
51 | public static final int scan_text=0x7f080000;
52 | public static final int scan_title=0x7f080002;
53 | }
54 | public static final class xml {
55 | public static final int config=0x7f040000;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/libs/cordova-2.9.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/libs/cordova-2.9.0.jar
--------------------------------------------------------------------------------
/libs/zxing2.3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/libs/zxing2.3.jar
--------------------------------------------------------------------------------
/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/barcode_back.9.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/res/drawable-hdpi/barcode_back.9.PNG
--------------------------------------------------------------------------------
/res/drawable-hdpi/barcode_back_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/barcode_bg.9.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/res/drawable-hdpi/barcode_bg.9.PNG
--------------------------------------------------------------------------------
/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/splashscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/res/drawable-hdpi/splashscreen.png
--------------------------------------------------------------------------------
/res/layout/activity_capture.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
16 |
17 |
22 |
23 |
32 |
33 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/res/raw/beep.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shixy/eoeh5/c4d23358e3408e134f92b9c1bbf44174684591ec/res/raw/beep.ogg
--------------------------------------------------------------------------------
/res/values/barcode.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | #b0000000
30 | #60000000
31 | #c0ffff00
32 |
33 | 将二维码放入框内, 即可自动扫描
34 | 返回
35 | 扫描登录
36 |
37 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | EOE H5版
3 |
4 |
--------------------------------------------------------------------------------
/res/xml/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
23 | eoe
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/BeepManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import java.io.IOException;
20 |
21 | import android.app.Activity;
22 | import android.content.Context;
23 | import android.content.res.AssetFileDescriptor;
24 | import android.media.AudioManager;
25 | import android.media.MediaPlayer;
26 | import android.os.Vibrator;
27 | import android.util.Log;
28 |
29 | import com.jingle.eoe.R;
30 |
31 | /**
32 | * 震动 蜂鸣 for {@link CaptureActivity}.
33 | */
34 | final class BeepManager {
35 |
36 | private static final String TAG = BeepManager.class.getSimpleName();
37 |
38 | private static final float BEEP_VOLUME = 0.10f;
39 | private static final long VIBRATE_DURATION = 200L;
40 |
41 | private final Activity activity;
42 | private MediaPlayer mediaPlayer;
43 | private boolean playBeep;
44 |
45 | // 可更改为配置参数
46 | private boolean shouldPlayBeep = true;
47 | private boolean vibrate = true;
48 |
49 | BeepManager(Activity activity) {
50 | this.activity = activity;
51 | this.mediaPlayer = null;
52 | updatePrefs();
53 | }
54 |
55 | void updatePrefs() {
56 | playBeep = shouldBeep();
57 | if (playBeep && mediaPlayer == null) {
58 | // The volume on STREAM_SYSTEM is not adjustable, and users found it
59 | // too loud,
60 | // so we now play on the music stream.
61 | activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
62 | mediaPlayer = buildMediaPlayer(activity);
63 | }
64 | }
65 |
66 | void playBeepSoundAndVibrate() {
67 | if (playBeep && mediaPlayer != null) {
68 | mediaPlayer.start();
69 | }
70 | if (vibrate) {
71 | Vibrator vibrator = (Vibrator) activity
72 | .getSystemService(Context.VIBRATOR_SERVICE);
73 | vibrator.vibrate(VIBRATE_DURATION);
74 | }
75 | }
76 |
77 | private boolean shouldBeep() {
78 | // See if sound settings overrides this
79 | AudioManager audioService = (AudioManager) activity
80 | .getSystemService(Context.AUDIO_SERVICE);
81 | if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
82 | shouldPlayBeep = false;
83 | }
84 | return shouldPlayBeep;
85 | }
86 |
87 | private static MediaPlayer buildMediaPlayer(Context activity) {
88 | MediaPlayer mediaPlayer = new MediaPlayer();
89 | mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
90 | // When the beep has finished playing, rewind to queue up another one.
91 | mediaPlayer
92 | .setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
93 | @Override
94 | public void onCompletion(MediaPlayer player) {
95 | player.seekTo(0);
96 | }
97 | });
98 |
99 | AssetFileDescriptor file = activity.getResources().openRawResourceFd(
100 | R.raw.beep);
101 | try {
102 | mediaPlayer.setDataSource(file.getFileDescriptor(),
103 | file.getStartOffset(), file.getLength());
104 | file.close();
105 | mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
106 | mediaPlayer.prepare();
107 | } catch (IOException ioe) {
108 | Log.w(TAG, ioe);
109 | mediaPlayer = null;
110 | }
111 | return mediaPlayer;
112 | }
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/CaptureActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import java.io.IOException;
20 | import java.util.Collection;
21 | import java.util.Map;
22 |
23 | import android.app.Activity;
24 | import android.content.Intent;
25 | import android.graphics.Bitmap;
26 | import android.os.Bundle;
27 | import android.os.Handler;
28 | import android.util.Log;
29 | import android.view.SurfaceHolder;
30 | import android.view.SurfaceView;
31 | import android.view.Window;
32 | import android.view.WindowManager;
33 | import android.widget.Toast;
34 |
35 | import com.google.zxing.BarcodeFormat;
36 | import com.google.zxing.DecodeHintType;
37 | import com.google.zxing.Result;
38 | import com.google.zxing.client.android.camera.CameraManager;
39 | import com.jingle.eoe.R;
40 |
41 | /**
42 | * 扫描界面
43 | */
44 | public final class CaptureActivity extends Activity implements
45 | SurfaceHolder.Callback {
46 |
47 | private static final String TAG = CaptureActivity.class.getSimpleName();
48 |
49 | public static final int HISTORY_REQUEST_CODE = 0x0000bacc;
50 |
51 | private CameraManager cameraManager;
52 | private CaptureActivityHandler handler;
53 | private ViewfinderView viewfinderView;
54 | private boolean hasSurface;
55 | private Collection decodeFormats;
56 | private Map decodeHints;
57 | private String characterSet;
58 | private InactivityTimer inactivityTimer;
59 | private BeepManager beepManager;
60 |
61 | ViewfinderView getViewfinderView() {
62 | return viewfinderView;
63 | }
64 |
65 | public Handler getHandler() {
66 | return handler;
67 | }
68 |
69 | CameraManager getCameraManager() {
70 | return cameraManager;
71 | }
72 |
73 | @Override
74 | public void onCreate(Bundle icicle) {
75 | super.onCreate(icicle);
76 |
77 | Window window = getWindow();
78 | window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
79 | setContentView(R.layout.activity_capture);
80 |
81 | hasSurface = false;
82 | inactivityTimer = new InactivityTimer(this);
83 | beepManager = new BeepManager(this);
84 |
85 | }
86 |
87 | @Override
88 | protected void onResume() {
89 | super.onResume();
90 |
91 | // CameraManager must be initialized here, not in onCreate(). This is
92 | // necessary because we don't
93 | // want to open the camera driver and measure the screen size if we're
94 | // going to show the help on
95 | // first launch. That led to bugs where the scanning rectangle was the
96 | // wrong size and partially
97 | // off screen.
98 | cameraManager = new CameraManager(getApplication());
99 |
100 | viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
101 | viewfinderView.setCameraManager(cameraManager);
102 |
103 | handler = null;
104 |
105 | SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
106 | SurfaceHolder surfaceHolder = surfaceView.getHolder();
107 | if (hasSurface) {
108 | // The activity was paused but not stopped, so the surface still
109 | // exists. Therefore
110 | // surfaceCreated() won't be called, so init the camera here.
111 | initCamera(surfaceHolder);
112 | } else {
113 | // Install the callback and wait for surfaceCreated() to init the
114 | // camera.
115 | surfaceHolder.addCallback(this);
116 | surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
117 | }
118 |
119 | beepManager.updatePrefs();
120 |
121 | inactivityTimer.onResume();
122 |
123 | Intent intent = getIntent();
124 |
125 | decodeFormats = null;
126 | characterSet = null;
127 |
128 | // 自定义扫描格式
129 | String decodeMode = intent.getStringExtra(Intents.Scan.MODE);
130 | decodeFormats = DecodeFormatManager.QR_CODE_FORMATS;
131 | if (decodeMode != null) {
132 | if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {
133 | decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;
134 | }
135 | if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {
136 | decodeFormats = DecodeFormatManager.QR_CODE_FORMATS;
137 | }
138 | if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {
139 | decodeFormats = DecodeFormatManager.DATA_MATRIX_FORMATS;
140 | }
141 | if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {
142 | decodeFormats = DecodeFormatManager.ONE_D_FORMATS;
143 | }
144 | } else {
145 | decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
146 | decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
147 | decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
148 | }
149 |
150 | decodeHints = DecodeHintManager.parseDecodeHints(intent);
151 |
152 | // 自定义扫描框大小
153 | if (intent.hasExtra(Intents.Scan.WIDTH)
154 | && intent.hasExtra(Intents.Scan.HEIGHT)) {
155 | int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
156 | int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
157 | if (width > 0 && height > 0) {
158 | cameraManager.setManualFramingRect(width, height);
159 | }
160 | }
161 |
162 | characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);
163 |
164 | }
165 |
166 | @Override
167 | protected void onPause() {
168 | if (handler != null) {
169 | handler.quitSynchronously();
170 | handler = null;
171 | }
172 | inactivityTimer.onPause();
173 | cameraManager.closeDriver();
174 | if (!hasSurface) {
175 | SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
176 | SurfaceHolder surfaceHolder = surfaceView.getHolder();
177 | surfaceHolder.removeCallback(this);
178 | }
179 | super.onPause();
180 | }
181 |
182 | @Override
183 | protected void onDestroy() {
184 | inactivityTimer.shutdown();
185 | super.onDestroy();
186 | }
187 |
188 | @Override
189 | public void surfaceCreated(SurfaceHolder holder) {
190 | if (holder == null) {
191 | Log.e(TAG,
192 | "*** WARNING *** surfaceCreated() gave us a null surface!");
193 | }
194 | if (!hasSurface) {
195 | hasSurface = true;
196 | initCamera(holder);
197 | }
198 | }
199 |
200 | @Override
201 | public void surfaceDestroyed(SurfaceHolder holder) {
202 | hasSurface = false;
203 | }
204 |
205 | @Override
206 | public void surfaceChanged(SurfaceHolder holder, int format, int width,
207 | int height) {
208 |
209 | }
210 |
211 | /**
212 | * 扫描成功,处理扫描结果
213 | *
214 | * @param rawResult
215 | * The contents of the barcode.
216 | * @param scaleFactor
217 | * amount by which thumbnail was scaled
218 | * @param barcode
219 | * A greyscale bitmap of the camera data which was decoded.
220 | */
221 | public void handleDecode(Result result, Bitmap barcode, float scaleFactor) {
222 | inactivityTimer.onActivity();
223 | beepManager.playBeepSoundAndVibrate();
224 | String resultString = result.getText();
225 | if (resultString.equals("")) {
226 | Toast.makeText(CaptureActivity.this, "扫码失败!", Toast.LENGTH_SHORT)
227 | .show();
228 | } else {
229 | Intent resultIntent = new Intent();
230 | Bundle bundle = new Bundle();
231 | bundle.putString("result", resultString);
232 | bundle.putString("format", result.getBarcodeFormat().toString());
233 | bundle.putParcelable("bitmap", barcode);
234 | resultIntent.putExtras(bundle);
235 | this.setResult(RESULT_OK, resultIntent);
236 | }
237 | CaptureActivity.this.finish();
238 | }
239 |
240 | private void initCamera(SurfaceHolder surfaceHolder) {
241 | if (surfaceHolder == null) {
242 | throw new IllegalStateException("No SurfaceHolder provided");
243 | }
244 | if (cameraManager.isOpen()) {
245 | Log.w(TAG,
246 | "initCamera() while already open -- late SurfaceView callback?");
247 | return;
248 | }
249 | try {
250 | cameraManager.openDriver(surfaceHolder);
251 | // Creating the handler starts the preview, which can also throw a
252 | // RuntimeException.
253 | if (handler == null) {
254 | handler = new CaptureActivityHandler(this, decodeFormats,
255 | decodeHints, characterSet, cameraManager);
256 | }
257 | } catch (IOException ioe) {
258 | Log.w(TAG, ioe);
259 | } catch (RuntimeException e) {
260 | // Barcode Scanner has seen crashes in the wild of this variety:
261 | // java.?lang.?RuntimeException: Fail to connect to camera service
262 | Log.w(TAG, "Unexpected error initializing camera", e);
263 | }
264 | }
265 |
266 | public void drawViewfinder() {
267 | viewfinderView.drawViewfinder();
268 | }
269 | }
270 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/CaptureActivityHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import java.util.Collection;
20 | import java.util.Map;
21 |
22 | import android.app.Activity;
23 | import android.content.Intent;
24 | import android.graphics.Bitmap;
25 | import android.graphics.BitmapFactory;
26 | import android.os.Bundle;
27 | import android.os.Handler;
28 | import android.os.Message;
29 | import android.util.Log;
30 |
31 | import com.google.zxing.BarcodeFormat;
32 | import com.google.zxing.DecodeHintType;
33 | import com.google.zxing.Result;
34 | import com.google.zxing.client.android.camera.CameraManager;
35 | import com.jingle.eoe.R;
36 |
37 | /**
38 | * This class handles all the messaging which comprises the state machine for
39 | * capture.
40 | *
41 | * @author dswitkin@google.com (Daniel Switkin)
42 | */
43 | public final class CaptureActivityHandler extends Handler {
44 |
45 | private static final String TAG = CaptureActivityHandler.class
46 | .getSimpleName();
47 |
48 | private final CaptureActivity activity;
49 | private final DecodeThread decodeThread;
50 | private State state;
51 | private final CameraManager cameraManager;
52 |
53 | private enum State {
54 | PREVIEW, SUCCESS, DONE
55 | }
56 |
57 | CaptureActivityHandler(CaptureActivity activity,
58 | Collection decodeFormats,
59 | Map baseHints, String characterSet,
60 | CameraManager cameraManager) {
61 | this.activity = activity;
62 | decodeThread = new DecodeThread(activity, decodeFormats, baseHints,
63 | characterSet, new ViewfinderResultPointCallback(
64 | activity.getViewfinderView()));
65 | decodeThread.start();
66 | state = State.SUCCESS;
67 |
68 | // Start ourselves capturing previews and decoding.
69 | this.cameraManager = cameraManager;
70 | cameraManager.startPreview();
71 | restartPreviewAndDecode();
72 | }
73 |
74 | @Override
75 | public void handleMessage(Message message) {
76 | switch (message.what) {
77 | case R.id.restart_preview:
78 | Log.d(TAG, "Got restart preview message");
79 | restartPreviewAndDecode();
80 | break;
81 | case R.id.decode_succeeded:
82 | Log.d(TAG, "Got decode succeeded message");
83 | state = State.SUCCESS;
84 | Bundle bundle = message.getData();
85 | Bitmap barcode = null;
86 | float scaleFactor = 1.0f;
87 | if (bundle != null) {
88 | byte[] compressedBitmap = bundle
89 | .getByteArray(DecodeThread.BARCODE_BITMAP);
90 | if (compressedBitmap != null) {
91 | barcode = BitmapFactory.decodeByteArray(compressedBitmap,
92 | 0, compressedBitmap.length, null);
93 | // Mutable copy:
94 | barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
95 | }
96 | scaleFactor = bundle
97 | .getFloat(DecodeThread.BARCODE_SCALED_FACTOR);
98 | }
99 | activity.handleDecode((Result) message.obj, barcode, scaleFactor);
100 | break;
101 | case R.id.decode_failed:
102 | // We're decoding as fast as possible, so when one decode fails,
103 | // start another.
104 | state = State.PREVIEW;
105 | cameraManager.requestPreviewFrame(decodeThread.getHandler(),
106 | R.id.decode);
107 | break;
108 | case R.id.return_scan_result:
109 | Log.d(TAG, "Got return scan result message");
110 | activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
111 | activity.finish();
112 | break;
113 | }
114 | }
115 |
116 | public void quitSynchronously() {
117 | state = State.DONE;
118 | cameraManager.stopPreview();
119 | Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
120 | quit.sendToTarget();
121 | try {
122 | // Wait at most half a second; should be enough time, and onPause()
123 | // will timeout quickly
124 | decodeThread.join(500L);
125 | } catch (InterruptedException e) {
126 | // continue
127 | }
128 |
129 | // Be absolutely sure we don't send any queued up messages
130 | removeMessages(R.id.decode_succeeded);
131 | removeMessages(R.id.decode_failed);
132 | }
133 |
134 | private void restartPreviewAndDecode() {
135 | if (state == State.SUCCESS) {
136 | state = State.PREVIEW;
137 | cameraManager.requestPreviewFrame(decodeThread.getHandler(),
138 | R.id.decode);
139 | activity.drawViewfinder();
140 | }
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/DecodeFormatManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import java.util.Arrays;
20 | import java.util.Collection;
21 | import java.util.EnumSet;
22 | import java.util.List;
23 | import java.util.regex.Pattern;
24 |
25 | import android.content.Intent;
26 | import android.net.Uri;
27 | import com.google.zxing.BarcodeFormat;
28 |
29 | final class DecodeFormatManager {
30 |
31 | private static final Pattern COMMA_PATTERN = Pattern.compile(",");
32 |
33 | static final Collection PRODUCT_FORMATS;
34 | static final Collection ONE_D_FORMATS;
35 | static final Collection QR_CODE_FORMATS = EnumSet
36 | .of(BarcodeFormat.QR_CODE);
37 | static final Collection DATA_MATRIX_FORMATS = EnumSet
38 | .of(BarcodeFormat.DATA_MATRIX);
39 | static {
40 | PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A, BarcodeFormat.UPC_E,
41 | BarcodeFormat.EAN_13, BarcodeFormat.EAN_8,
42 | BarcodeFormat.RSS_14, BarcodeFormat.RSS_EXPANDED);
43 | ONE_D_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,
44 | BarcodeFormat.CODE_93, BarcodeFormat.CODE_128,
45 | BarcodeFormat.ITF, BarcodeFormat.CODABAR);
46 | ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
47 | }
48 |
49 | private DecodeFormatManager() {
50 | }
51 |
52 | static Collection parseDecodeFormats(Intent intent) {
53 | List scanFormats = null;
54 | String scanFormatsString = intent.getStringExtra(Intents.Scan.FORMATS);
55 | if (scanFormatsString != null) {
56 | scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString));
57 | }
58 | return parseDecodeFormats(scanFormats,
59 | intent.getStringExtra(Intents.Scan.MODE));
60 | }
61 |
62 | static Collection parseDecodeFormats(Uri inputUri) {
63 | List formats = inputUri
64 | .getQueryParameters(Intents.Scan.FORMATS);
65 | if (formats != null && formats.size() == 1 && formats.get(0) != null) {
66 | formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
67 | }
68 | return parseDecodeFormats(formats,
69 | inputUri.getQueryParameter(Intents.Scan.MODE));
70 | }
71 |
72 | private static Collection parseDecodeFormats(
73 | Iterable scanFormats, String decodeMode) {
74 | if (scanFormats != null) {
75 | Collection formats = EnumSet
76 | .noneOf(BarcodeFormat.class);
77 | try {
78 | for (String format : scanFormats) {
79 | formats.add(BarcodeFormat.valueOf(format));
80 | }
81 | return formats;
82 | } catch (IllegalArgumentException iae) {
83 | // ignore it then
84 | }
85 | }
86 | if (decodeMode != null) {
87 | if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {
88 | return PRODUCT_FORMATS;
89 | }
90 | if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {
91 | return QR_CODE_FORMATS;
92 | }
93 | if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {
94 | return DATA_MATRIX_FORMATS;
95 | }
96 | if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {
97 | return ONE_D_FORMATS;
98 | }
99 | }
100 | return null;
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/DecodeHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import java.io.ByteArrayOutputStream;
20 | import java.util.Map;
21 |
22 | import android.graphics.Bitmap;
23 | import android.os.Bundle;
24 | import android.os.Handler;
25 | import android.os.Looper;
26 | import android.os.Message;
27 | import android.util.Log;
28 |
29 | import com.google.zxing.BinaryBitmap;
30 | import com.google.zxing.DecodeHintType;
31 | import com.google.zxing.MultiFormatReader;
32 | import com.google.zxing.PlanarYUVLuminanceSource;
33 | import com.google.zxing.ReaderException;
34 | import com.google.zxing.Result;
35 | import com.google.zxing.common.HybridBinarizer;
36 | import com.jingle.eoe.R;
37 |
38 | final class DecodeHandler extends Handler {
39 |
40 | private static final String TAG = DecodeHandler.class.getSimpleName();
41 |
42 | private final CaptureActivity activity;
43 | private final MultiFormatReader multiFormatReader;
44 | private boolean running = true;
45 |
46 | DecodeHandler(CaptureActivity activity, Map hints) {
47 | multiFormatReader = new MultiFormatReader();
48 | multiFormatReader.setHints(hints);
49 | this.activity = activity;
50 | }
51 |
52 | @Override
53 | public void handleMessage(Message message) {
54 | if (!running) {
55 | return;
56 | }
57 | switch (message.what) {
58 | case R.id.decode:
59 | decode((byte[]) message.obj, message.arg1, message.arg2);
60 | break;
61 | case R.id.quit:
62 | running = false;
63 | Looper.myLooper().quit();
64 | break;
65 | }
66 | }
67 |
68 | /**
69 | * Decode the data within the viewfinder rectangle, and time how long it
70 | * took. For efficiency, reuse the same reader objects from one decode to
71 | * the next.
72 | *
73 | * @param data
74 | * The YUV preview frame.
75 | * @param width
76 | * The width of the preview frame.
77 | * @param height
78 | * The height of the preview frame.
79 | */
80 | private void decode(byte[] data, int width, int height) {
81 | long start = System.currentTimeMillis();
82 | Result rawResult = null;
83 | // 横屏变竖屏
84 | byte[] rotatedData = new byte[data.length];
85 | for (int y = 0; y < height; y++) {
86 | for (int x = 0; x < width; x++)
87 | rotatedData[x * height + height - y - 1] = data[x + y * width];
88 | }
89 | int tmp = width;
90 | width = height;
91 | height = tmp;
92 | data = rotatedData;
93 |
94 | PlanarYUVLuminanceSource source = activity.getCameraManager()
95 | .buildLuminanceSource(data, width, height);
96 | if (source != null) {
97 | BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
98 | try {
99 | rawResult = multiFormatReader.decodeWithState(bitmap);
100 | } catch (ReaderException re) {
101 | // continue
102 | } finally {
103 | multiFormatReader.reset();
104 | }
105 | }
106 |
107 | Handler handler = activity.getHandler();
108 | if (rawResult != null) {
109 | // Don't log the barcode contents for security.
110 | long end = System.currentTimeMillis();
111 | Log.d(TAG, "Found barcode in " + (end - start) + " ms");
112 | if (handler != null) {
113 | Message message = Message.obtain(handler,
114 | R.id.decode_succeeded, rawResult);
115 | Bundle bundle = new Bundle();
116 | bundleThumbnail(source, bundle);
117 | message.setData(bundle);
118 | message.sendToTarget();
119 | }
120 | } else {
121 | if (handler != null) {
122 | Message message = Message.obtain(handler, R.id.decode_failed);
123 | message.sendToTarget();
124 | }
125 | }
126 | }
127 |
128 | private static void bundleThumbnail(PlanarYUVLuminanceSource source,
129 | Bundle bundle) {
130 | int[] pixels = source.renderThumbnail();
131 | int width = source.getThumbnailWidth();
132 | int height = source.getThumbnailHeight();
133 | Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height,
134 | Bitmap.Config.ARGB_8888);
135 | ByteArrayOutputStream out = new ByteArrayOutputStream();
136 | bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
137 | bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
138 | bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width
139 | / source.getWidth());
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/DecodeHintManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import java.util.EnumMap;
20 | import java.util.HashMap;
21 | import java.util.Map;
22 | import java.util.regex.Pattern;
23 |
24 | import android.content.Intent;
25 | import android.net.Uri;
26 | import android.os.Bundle;
27 | import android.util.Log;
28 |
29 | import com.google.zxing.DecodeHintType;
30 |
31 | /**
32 | * @author Lachezar Dobrev
33 | */
34 | final class DecodeHintManager {
35 |
36 | private static final String TAG = DecodeHintManager.class.getSimpleName();
37 |
38 | // This pattern is used in decoding integer arrays.
39 | private static final Pattern COMMA = Pattern.compile(",");
40 |
41 | private DecodeHintManager() {
42 | }
43 |
44 | /**
45 | *
46 | * Split a query string into a list of name-value pairs.
47 | *
48 | *
49 | *
50 | * This is an alternative to the {@link Uri#getQueryParameterNames()} and
51 | * {@link Uri#getQueryParameters(String)}, which are quirky and not suitable
52 | * for exist-only Uri parameters.
53 | *
54 | *
55 | *
56 | * This method ignores multiple parameters with the same name and returns
57 | * the first one only. This is technically incorrect, but should be
58 | * acceptable due to the method of processing Hints: no multiple values for
59 | * a hint.
60 | *
61 | *
62 | * @param query
63 | * query to split
64 | * @return name-value pairs
65 | */
66 | private static Map splitQuery(String query) {
67 | Map map = new HashMap();
68 | int pos = 0;
69 | while (pos < query.length()) {
70 | if (query.charAt(pos) == '&') {
71 | // Skip consecutive ampersand separators.
72 | pos++;
73 | continue;
74 | }
75 | int amp = query.indexOf('&', pos);
76 | int equ = query.indexOf('=', pos);
77 | if (amp < 0) {
78 | // This is the last element in the query, no more ampersand
79 | // elements.
80 | String name;
81 | String text;
82 | if (equ < 0) {
83 | // No equal sign
84 | name = query.substring(pos);
85 | name = name.replace('+', ' '); // Preemptively decode +
86 | name = Uri.decode(name);
87 | text = "";
88 | } else {
89 | // Split name and text.
90 | name = query.substring(pos, equ);
91 | name = name.replace('+', ' '); // Preemptively decode +
92 | name = Uri.decode(name);
93 | text = query.substring(equ + 1);
94 | text = text.replace('+', ' '); // Preemptively decode +
95 | text = Uri.decode(text);
96 | }
97 | if (!map.containsKey(name)) {
98 | map.put(name, text);
99 | }
100 | break;
101 | }
102 | if (equ < 0 || equ > amp) {
103 | // No equal sign until the &: this is a simple parameter with no
104 | // value.
105 | String name = query.substring(pos, amp);
106 | name = name.replace('+', ' '); // Preemptively decode +
107 | name = Uri.decode(name);
108 | if (!map.containsKey(name)) {
109 | map.put(name, "");
110 | }
111 | pos = amp + 1;
112 | continue;
113 | }
114 | String name = query.substring(pos, equ);
115 | name = name.replace('+', ' '); // Preemptively decode +
116 | name = Uri.decode(name);
117 | String text = query.substring(equ + 1, amp);
118 | text = text.replace('+', ' '); // Preemptively decode +
119 | text = Uri.decode(text);
120 | if (!map.containsKey(name)) {
121 | map.put(name, text);
122 | }
123 | pos = amp + 1;
124 | }
125 | return map;
126 | }
127 |
128 | static Map parseDecodeHints(Uri inputUri) {
129 | String query = inputUri.getEncodedQuery();
130 | if (query == null || query.length() == 0) {
131 | return null;
132 | }
133 |
134 | // Extract parameters
135 | Map parameters = splitQuery(query);
136 |
137 | Map hints = new EnumMap(
138 | DecodeHintType.class);
139 |
140 | for (DecodeHintType hintType : DecodeHintType.values()) {
141 |
142 | if (hintType == DecodeHintType.CHARACTER_SET
143 | || hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK
144 | || hintType == DecodeHintType.POSSIBLE_FORMATS) {
145 | continue; // This hint is specified in another way
146 | }
147 |
148 | String parameterName = hintType.name();
149 | String parameterText = parameters.get(parameterName);
150 | if (parameterText == null) {
151 | continue;
152 | }
153 | if (hintType.getValueType().equals(Object.class)) {
154 | // This is an unspecified type of hint content. Use the value as
155 | // is.
156 | // TODO: Can we make a different assumption on this?
157 | hints.put(hintType, parameterText);
158 | continue;
159 | }
160 | if (hintType.getValueType().equals(Void.class)) {
161 | // Void hints are just flags: use the constant specified by
162 | // DecodeHintType
163 | hints.put(hintType, Boolean.TRUE);
164 | continue;
165 | }
166 | if (hintType.getValueType().equals(String.class)) {
167 | // A string hint: use the decoded value.
168 | hints.put(hintType, parameterText);
169 | continue;
170 | }
171 | if (hintType.getValueType().equals(Boolean.class)) {
172 | // A boolean hint: a few values for false, everything else is
173 | // true.
174 | // An empty parameter is simply a flag-style parameter, assuming
175 | // true
176 | if (parameterText.length() == 0) {
177 | hints.put(hintType, Boolean.TRUE);
178 | } else if ("0".equals(parameterText)
179 | || "false".equalsIgnoreCase(parameterText)
180 | || "no".equalsIgnoreCase(parameterText)) {
181 | hints.put(hintType, Boolean.FALSE);
182 | } else {
183 | hints.put(hintType, Boolean.TRUE);
184 | }
185 |
186 | continue;
187 | }
188 | if (hintType.getValueType().equals(int[].class)) {
189 | // An integer array. Used to specify valid lengths.
190 | // Strip a trailing comma as in Java style array initialisers.
191 | if (parameterText.length() > 0
192 | && parameterText.charAt(parameterText.length() - 1) == ',') {
193 | parameterText = parameterText.substring(0,
194 | parameterText.length() - 1);
195 | }
196 | String[] values = COMMA.split(parameterText);
197 | int[] array = new int[values.length];
198 | for (int i = 0; i < values.length; i++) {
199 | try {
200 | array[i] = Integer.parseInt(values[i]);
201 | } catch (NumberFormatException ignored) {
202 | Log.w(TAG, "Skipping array of integers hint "
203 | + hintType + " due to invalid numeric value: '"
204 | + values[i] + '\'');
205 | array = null;
206 | break;
207 | }
208 | }
209 | if (array != null) {
210 | hints.put(hintType, array);
211 | }
212 | continue;
213 | }
214 | Log.w(TAG, "Unsupported hint type '" + hintType + "' of type "
215 | + hintType.getValueType());
216 | }
217 |
218 | Log.i(TAG, "Hints from the URI: " + hints);
219 | return hints;
220 | }
221 |
222 | static Map parseDecodeHints(Intent intent) {
223 | Bundle extras = intent.getExtras();
224 | if (extras == null || extras.isEmpty()) {
225 | return null;
226 | }
227 | Map hints = new EnumMap(
228 | DecodeHintType.class);
229 |
230 | for (DecodeHintType hintType : DecodeHintType.values()) {
231 |
232 | if (hintType == DecodeHintType.CHARACTER_SET
233 | || hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK
234 | || hintType == DecodeHintType.POSSIBLE_FORMATS) {
235 | continue; // This hint is specified in another way
236 | }
237 |
238 | String hintName = hintType.name();
239 | if (extras.containsKey(hintName)) {
240 | if (hintType.getValueType().equals(Void.class)) {
241 | // Void hints are just flags: use the constant specified by
242 | // the DecodeHintType
243 | hints.put(hintType, Boolean.TRUE);
244 | } else {
245 | Object hintData = extras.get(hintName);
246 | if (hintType.getValueType().isInstance(hintData)) {
247 | hints.put(hintType, hintData);
248 | } else {
249 | Log.w(TAG, "Ignoring hint " + hintType
250 | + " because it is not assignable from "
251 | + hintData);
252 | }
253 | }
254 | }
255 | }
256 |
257 | Log.i(TAG, "Hints from the Intent: " + hints);
258 | return hints;
259 | }
260 |
261 | }
262 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/DecodeThread.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import java.util.Collection;
20 | import java.util.EnumMap;
21 | import java.util.Map;
22 | import java.util.concurrent.CountDownLatch;
23 |
24 | import android.os.Handler;
25 | import android.os.Looper;
26 | import android.util.Log;
27 |
28 | import com.google.zxing.BarcodeFormat;
29 | import com.google.zxing.DecodeHintType;
30 | import com.google.zxing.ResultPointCallback;
31 |
32 | /**
33 | * This thread does all the heavy lifting of decoding the images.
34 | *
35 | * @author dswitkin@google.com (Daniel Switkin)
36 | */
37 | final class DecodeThread extends Thread {
38 |
39 | public static final String BARCODE_BITMAP = "barcode_bitmap";
40 | public static final String BARCODE_SCALED_FACTOR = "barcode_scaled_factor";
41 |
42 | private final CaptureActivity activity;
43 | private final Map hints;
44 | private Handler handler;
45 | private final CountDownLatch handlerInitLatch;
46 |
47 | DecodeThread(CaptureActivity activity,
48 | Collection decodeFormats,
49 | Map baseHints, String characterSet,
50 | ResultPointCallback resultPointCallback) {
51 |
52 | this.activity = activity;
53 | handlerInitLatch = new CountDownLatch(1);
54 |
55 | hints = new EnumMap(DecodeHintType.class);
56 | if (baseHints != null) {
57 | hints.putAll(baseHints);
58 | }
59 |
60 | hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
61 |
62 | if (characterSet != null) {
63 | hints.put(DecodeHintType.CHARACTER_SET, characterSet);
64 | }
65 | hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK,
66 | resultPointCallback);
67 | Log.i("DecodeThread", "Hints: " + hints);
68 | }
69 |
70 | Handler getHandler() {
71 | try {
72 | handlerInitLatch.await();
73 | } catch (InterruptedException ie) {
74 | // continue?
75 | }
76 | return handler;
77 | }
78 |
79 | @Override
80 | public void run() {
81 | Looper.prepare();
82 | handler = new DecodeHandler(activity, hints);
83 | handlerInitLatch.countDown();
84 | Looper.loop();
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/FinishListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import android.app.Activity;
20 | import android.content.DialogInterface;
21 |
22 | /**
23 | * Simple listener used to exit the app in a few cases.
24 | *
25 | * @author Sean Owen
26 | */
27 | public final class FinishListener implements DialogInterface.OnClickListener,
28 | DialogInterface.OnCancelListener {
29 |
30 | private final Activity activityToFinish;
31 |
32 | public FinishListener(Activity activityToFinish) {
33 | this.activityToFinish = activityToFinish;
34 | }
35 |
36 | @Override
37 | public void onCancel(DialogInterface dialogInterface) {
38 | run();
39 | }
40 |
41 | @Override
42 | public void onClick(DialogInterface dialogInterface, int i) {
43 | run();
44 | }
45 |
46 | private void run() {
47 | activityToFinish.finish();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/com/google/zxing/client/android/InactivityTimer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.zxing.client.android;
18 |
19 | import android.app.Activity;
20 | import android.content.BroadcastReceiver;
21 | import android.content.Context;
22 | import android.content.Intent;
23 | import android.content.IntentFilter;
24 | import android.os.AsyncTask;
25 | import android.os.BatteryManager;
26 | import android.util.Log;
27 |
28 | import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
29 | import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
30 |
31 | /**
32 | * Finishes an activity after a period of inactivity if the device is on battery
33 | * power.
34 | */
35 | final class InactivityTimer {
36 |
37 | private static final String TAG = InactivityTimer.class.getSimpleName();
38 |
39 | private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
40 |
41 | private final Activity activity;
42 | private final AsyncTaskExecInterface taskExec;
43 | private final BroadcastReceiver powerStatusReceiver;
44 | private InactivityAsyncTask inactivityTask;
45 |
46 | InactivityTimer(Activity activity) {
47 | this.activity = activity;
48 | taskExec = new AsyncTaskExecManager().build();
49 | powerStatusReceiver = new PowerStatusReceiver();
50 | onActivity();
51 | }
52 |
53 | synchronized void onActivity() {
54 | cancel();
55 | inactivityTask = new InactivityAsyncTask();
56 | taskExec.execute(inactivityTask);
57 | }
58 |
59 | public void onPause() {
60 | cancel();
61 | activity.unregisterReceiver(powerStatusReceiver);
62 | }
63 |
64 | public void onResume() {
65 | activity.registerReceiver(powerStatusReceiver, new IntentFilter(
66 | Intent.ACTION_BATTERY_CHANGED));
67 | onActivity();
68 | }
69 |
70 | private synchronized void cancel() {
71 | AsyncTask, ?, ?> task = inactivityTask;
72 | if (task != null) {
73 | task.cancel(true);
74 | inactivityTask = null;
75 | }
76 | }
77 |
78 | void shutdown() {
79 | cancel();
80 | }
81 |
82 | private final class PowerStatusReceiver extends BroadcastReceiver {
83 | @Override
84 | public void onReceive(Context context, Intent intent) {
85 | if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
86 | // 0 indicates that we're on battery
87 | boolean onBatteryNow = intent.getIntExtra(
88 | BatteryManager.EXTRA_PLUGGED, -1) <= 0;
89 | if (onBatteryNow) {
90 | InactivityTimer.this.onActivity();
91 | } else {
92 | InactivityTimer.this.cancel();
93 | }
94 | }
95 | }
96 | }
97 |
98 | private final class InactivityAsyncTask extends
99 | AsyncTask