Android生成商品条形码的例子
简介
商品条码,或者EAN是欧洲标准条码。该条码被作为商品和商品制造商的唯一标识,同时,是美国标准UPC的超集。EAN-13由前十二位数字和第十三位作为校验位的数字组成。其中第十三位数字由前十二位数字按照一定公式计算得出。
如今,各个领域都有条码的应用。如果你以写代码为生,你的程序需要支持条码是早晚的事儿。比如超市的会员打折系统,用户以手机获取的条码作为唯一标识,来获得折扣。又比如支付系统中的星巴克支付系统。本文中,我们将讨论如何在安卓系统中生成EAN-13条码。
EAN-13计算基础
EAN-13采用的是是各位商品码,第十三位作为校验位。该校验位有前十二位数字生成。生成校验位的算法如下(数据从左到右计数):
P1 = 偶数位的数字和
P2 = 奇数位的数字和
Z = P1 + 3 * P2
R = 取个位数作为Z值
校验位 = R - Z
下面我们看一下EAN-13的编码结构:
首位不参与计算
随后六位根据首位数字编码
末六位以下列规则转换
首位 左六位 右六位
0 LLLLLL RRRRRR
1 LLGLGG RRRRRR
2 LLGGLG RRRRRR
3 LLGGGL RRRRRR
4 LGLLGG RRRRRR
5 LGGLLG RRRRRR
6 LGGGLL RRRRRR
7 LGLGLG RRRRRR
8 LGLGGL RRRRRR
9 LGGLGL RRRRRR
位编码:
Digit L - code G - code R - code
0 0001101 0100111 1110010
1 0011001 0110011 1100110
2 0010011 0011011 1101100
3 0111101 0100001 1000010
4 0100011 0011101 1011100
5 0110001 0111001 1001110
6 0101111 0000101 1010000
7 0111011 0010001 1000100
8 0110111 0001001 1001000
9 0001011 0010111 1110100
应用
文章尾部,我贴出了一个用十二位数字生成EAN-13条码的类EAN13CodeBuilder。这个类可以把生成的十三位数字的每一位都替换为可以展示到屏幕的特殊字体。该字体包括了一些特殊字符,比如$,+,!和其如上所述的十个数字的编码L,R,G。在EAN-13条码必须以以下方式生成:起始界定符(取决于第一位数字)-左六位-中间分隔符-右六位-终止符(!)
Digit L - code G - code R -code Start delimiter
0 0 A a #!
1 1 B b $!
2 2 C c %!
3 3 D d &!
4 4 E e '!
5 5 F f (!
6 6 G g )!
7 7 H h *!
8 8 I i +!
9 9 J j ,!
我们需要做的,仅仅是用数字生成正确的字符串,并用特殊字体展示而已。
这个类的使用非常简单。它将原始字符串传递给构造函数,之后调用getcode()方法取回EAN-13条码。这个类的源代码如下:
代码如下 | 复制代码 |
public class EAN13CodeBuilder { private String codeStringValue; private String generatedCode; public EAN13CodeBuilder(String codeString) { codeStringValue = codeString; parse(); } public String getCode() { return generatedCode; } //////////////////////////////////////////////////////////////// // this method generates EAN 13 control number ans returns full // string to encode private String getFullCode() { int chetVal = 0, nechetVal = 0; String codeToParse = codeStringValue; for( int index = 0;index<6;index++ ) { chetVal += Integer.valueOf(codeToParse.substring( index*2+1,index*2+2)).intValue(); nechetVal += Integer.valueOf(codeToParse.substring( index*2,index*2+1)).intValue(); } chetVal *= 3; int controlNumber = 10 - (chetVal+nechetVal)%10; if( controlNumber == 10 ) controlNumber = 0; codeToParse += String.valueOf(controlNumber); return codeToParse; } private String DigitToUpperCase( String digit) { String letters = "ABCDEFGHIJ"; int position = Integer.valueOf(digit).intValue(); String retVal = letters.substring(position,position+1); return retVal; } private String DigitToLowerCase( String digit) { String letters = "abcdefghij"; int position = Integer.valueOf(digit).intValue(); String retVal = letters.substring(position,position+1); return retVal; } ////////////////////////////////////////////// // this method generates EAN 13 encoded string // algorithm can be found at http://en.wikipedia.org/wiki/EAN-13 private String createEAN13Code(String rawCode) { int firstFlag = Integer.valueOf( rawCode.substring(0,1) ).intValue(); String leftString = rawCode.substring(1,7); String rightString = rawCode.substring(7); String rightCode = ""; String leftCode = ""; for( int i=0;i<6;i++) { rightCode += DigitToLowerCase( rightString.substring(i,i+1) ); } if( firstFlag == 0 ) { leftCode = "#!"+leftString.substring(0,1) +leftString.substring(1,2) +leftString.substring(2,3) +leftString.substring(3,4) +leftString.substring(4,5) +leftString.substring(5); } if( firstFlag == 1 ) { leftCode = "$!"+leftString.substring(0,1) +leftString.substring(1,2) +DigitToUpperCase(leftString.substring(2,3)) +leftString.substring(3,4) +DigitToUpperCase(leftString.substring(4,5)) +DigitToUpperCase(leftString.substring(5)); } if( firstFlag == 2 ) { leftCode = "%!"+leftString.substring(0,1) +leftString.substring(1,2) +DigitToUpperCase(leftString.substring(2,3)) +DigitToUpperCase(leftString.substring(3,4)) +leftString.substring(4,5) +DigitToUpperCase(leftString.substring(5)); } if( firstFlag == 3 ) { leftCode = "&!"+leftString.substring(0,1) +leftString.substring(1,2) +DigitToUpperCase(leftString.substring(2,3)) +DigitToUpperCase(leftString.substring(3,4)) +DigitToUpperCase(leftString.substring(4,5)) +leftString.substring(5); } if( firstFlag == 4 ) { leftCode = "'!"+leftString.substring(0,1) +DigitToUpperCase(leftString.substring(1,2)) +leftString.substring(2,3) +leftString.substring(3,4) +DigitToUpperCase(leftString.substring(4,5)) +DigitToUpperCase(leftString.substring(5)); } if( firstFlag == 5 ) { leftCode = "(!"+leftString.substring(0,1) +DigitToUpperCase(leftString.substring(1,2)) +DigitToUpperCase(leftString.substring(2,3)) +leftString.substring(3,4) +leftString.substring(4,5) +DigitToUpperCase(leftString.substring(5)); } if( firstFlag == 6 ) { leftCode = ")!"+leftString.substring(0,1) +DigitToUpperCase(leftString.substring(1,2)) +DigitToUpperCase(leftString.substring(2,3)) +DigitToUpperCase(leftString.substring(3,4)) +leftString.substring(4,5) +leftString.substring(5); } if( firstFlag == 7 ) { leftCode = "*!"+leftString.substring(0,1) +DigitToUpperCase(leftString.substring(1,2)) +leftString.substring(2,3) +DigitToUpperCase(leftString.substring(3,4)) +leftString.substring(4,5) +DigitToUpperCase(leftString.substring(5)); } if( firstFlag == 8 ) { leftCode = "+!"+leftString.substring(0,1) +DigitToUpperCase(leftString.substring(1,2)) +leftString.substring(2,3) +DigitToUpperCase(leftString.substring(3,4)) +DigitToUpperCase(leftString.substring(4,5)) +leftString.substring(5); } if( firstFlag == 9 ) { leftCode = ",!"+leftString.substring(0,1) +DigitToUpperCase(leftString.substring(1,2)) +DigitToUpperCase(leftString.substring(2,3)) +leftString.substring(3,4) +DigitToUpperCase(leftString.substring(4,5)) +leftString.substring(5); } String retVal = leftCode + "-" + rightCode + "!"; return retVal; } private void parse() { String fullString = getFullCode(); System.out.println( "Full code: " + fullString ); generatedCode = createEAN13Code(fullString); System.out.println( "Generated code: " + generatedCode ); } } |
代码
为了生成一个在线条码,并将它展示到安卓屏幕上,你可能需要自己生成条码并用其中的特殊字符展示到屏幕上。为了在安卓系统的TextView 部件中设置字符集,你需要在工程文件的 /assets 下放置一个文件,加载Typeface 并且设置Typeface 到TextView 中:
代码如下 | 复制代码 |
import android.app.Activity; |
使用如下语句创建一个cordova应用:
代码如下 | 复制代码 |
cordova -d create lzwmeapp com.lzw.lzwmeapp lzwmeapp |
但是无法成功创建,提示错误如下:
代码如下 | 复制代码 |
E:lzwme_app_android>cordova -d create lzwmeapp Creating a new cordova project with name “HelloCordova” and id “io.cordova.hello cordova” at location “E:lzwme_app_androidlzwmeapp” Using stock cordova hello-world application. Requesting {“uri”:”https://git-wip-us.apache.org/repos/asf?p=cordova-app-hello-w orld.git;a=snapshot;h=3.4.0;sf=tgz”}… Downloading cordova library for www… Error: connect ETIMEDOUT at errnoException (net.js:904:11) at Object.afterConnect [as oncomplete] (net.js:895:19) |
明显这是下载 cordova hello world 文件失败。主要原因为网址 https://git-wip-us.apache.org/ 速度太慢,容易超时。
解决方法:
我们可以变更这个文件的下载地址,方法如下:
打开 cordova 目录下的platforms.js文件,修改其中的url配置地址。这里可以修改为git附件包下载地址,具体到官方github查找:
https://github.com/apache/
如这里主要修改了如下部分代码:
代码如下 | 复制代码 |
‘android’ : { parser : ‘./src/metadata/android_parser’, //url : ‘https://git-wip-us.apache.org/repos/asf?p=cordova-android.git’, url : ‘https://github.com/apache/cordova-android/archive/3.4.0.tar.gz?’, version: ’3.4.0′ }, ‘www’:{ hostos : [], //url : ‘https://git-wip-us.apache.org/repos/asf?p=cordova-app-hello-world.git’, url : ‘https://github.com/apache/cordova-app-hello-world/archive/3.4.0.tar.gz?’, version: ’3.4.0′ } |
其他部分的url也可参照修改。
当然,你也可以手动下载对应的压缩包,放到本地服务器,然后修改为相应文件的下载地址。
例子
代码如下 | 复制代码 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <HorizontalScrollView <TextView <TableLayout <TableRow <Button <Button <Button <Button <Button <TableRow <Button <Button <Button <Button <Button <LinearLayout <TableLayout <TableRow <Button <Button <Button <TableRow <Button <Button <Button <Button <LinearLayout <Button <Button </LinearLayout> |
MainActivity类和之前的java计算器差不多:
代码如下 | 复制代码 |
package me.jerrys.calc; import java.math.BigDecimal; import android.support.v7.app.ActionBarActivity; public class MainActivity extends ActionBarActivity { @Override public void onClickListener(View v) { public void addNumber(String num) { |
-
如何在圆弧内绘制图片?
-
如何让列表按照圆弧的轨迹滑动?
-
P(x) = centerX + cos(alpha) *r.
-
P(y) = centerY - sin(alpha) * r.
我讲创建一个展示的列表作为样例。列表中的图片来自于资源文件夹。你可以参考我上传的源代码.
代码如下 | 复制代码 |
int[] playerDrawableResourceIds = new int[] { R.drawable.ronaldo, |
如何在圆弧中绘制图片?
首先,创建一个列表项的类CircleDrawItem.
代码如下 | 复制代码 |
public class CircleDrawItem { public Bitmap mIconBitmap; public double mAngle; } |
mIconBitmap: 列表项的位图.
mAngle: 每个列表项的弧度。这个弧度在旋转列表项的时候会被更新.
因为该圆弧将被在屏幕左侧展示。所以圆心将会把X坐标设置为负数。同时,Y坐标将被设置为屏幕中心的Y坐标值.
代码如下 | 复制代码 |
mCenterX = (int) (-Global.dp * 200); mCenterY = (int) (Global.dh / 2.0f); mRadius = (int) (450 * Global.dp); mStartAngleInRadian = Math.PI / 4; |
用Global 的值进行计算:
代码如下 | 复制代码 |
Global.dw = getResources().getDisplayMetrics().widthPixels; Global.dh = getResources().getDisplayMetrics().heightPixels; Global.dp = Global.density / 1.5f; |
这个圆弧保有CircleDrawItem的数组列表。第一项的弧度为PI/4。每个列表项的间隔是PI/10.第一项的弧度和两项间的弧度可以根据你的需求进行修改。
代码如下 | 复制代码 |
for (int i = 0; i < playerDrawableResourceIds.length; i++) { CircleDrawItem circleDrawItem = new CircleDrawItem(); circleDrawItem.mIconBitmap = decodeSampledBitmapFromResource( getResources(), playerDrawableResourceIds[i], 50, 50); circleDrawItem.mAngle = mStartAngleInRadian - i * Math.PI / 10; datas.add(circleDrawItem); } |
我创建了一个线程,以便将每个数据项绘制到圆弧中。
代码如下 | 复制代码 |
protected void draw() { Canvas canvas = getHolder().lockCanvas(); if (canvas == null) { return; } canvas.save(); canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setAntiAlias(true); for (int i = 0; i < datas.size(); i++) { canvas.save(); CircleDrawItem item = datas.get(i); double x = mCenterX + Math.cos(item.mAngle) * mRadius; double y = mCenterY - Math.sin(item.mAngle) * mRadius; canvas.drawBitmap(item.mIconBitmap, (int) x - item.mIconBitmap.getWidth() / 2, (int) y - item.mIconBitmap.getHeight() / 2, paint); canvas.restore(); } canvas.restore(); getHolder().unlockCanvasAndPost(canvas); } |
如何让列表在圆弧中滑动?
引用OnGestureListener 并重载onScroll()函数。
代码如下 | 复制代码 |
|
计算滑动角度的方法如下:
代码如下 | 复制代码 |
|
相关文章
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 本文介绍两种使用 php 生成二维码的方法。 (1)利用google生成二维码的开放接口,代码如下: /** * google api 二维码生成【QRcode可以存储最多4296个字母数字类型的任意文本,具体可以查看二维码数据格式】 * @param strin...2015-10-21
- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
- 这篇文章主要介绍了C#生成随机数功能,涉及C#数学运算与字符串操作相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 关于生成唯一数字ID的问题,是不是需要使用rand生成一个随机数,然后去数据库查询是否有这个数呢?感觉这样的话有点费时间,有没有其他方法呢?当然不是,其实有两种方法可以解决。 1. 如果你只用php而不用数据库的话,那时间戳+随...2015-11-24
- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
- 下面小编就为大家带来一篇jQuery为动态生成的select元素添加事件的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-09-01
- 经常制作开发不同的网站的后台,写过很多种不同的后台导航写法。 最终积累了这种最写法,算是最好的吧...2013-09-29
- 首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20