- 浏览: 636453 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (314)
- 生活 (2)
- c# (37)
- 技术 (3)
- 400电话 (0)
- 400常见问题 (0)
- 400资费 (0)
- html (7)
- css (0)
- 数据库 (7)
- javascript (16)
- php (33)
- asp.net mvc2 (10)
- mysql (9)
- C# 3.0 LinQ (10)
- vs2005或vs2008 (4)
- flash and as3 (7)
- fms (1)
- dedeCMS (11)
- java (33)
- j2me (1)
- swing (1)
- c++ (1)
- jquery easyui (3)
- jquery (5)
- android (29)
- MongoDB (9)
- VtigerCRM (1)
- test (0)
- linux (30)
- nutch (2)
- SqlServer数据库 (2)
- 数据检索 (2)
- java抓取 (11)
- 乐天 (1)
- 淘宝 (1)
- Silverlight4.0 (6)
- sphinx实时索引 (5)
- ecshop (9)
- codeigniter(CI) (3)
- axure6 (1)
- 京东店铺装修教程 (2)
- xpath (1)
- joomla (2)
- bpm (1)
- Bootstrap (2)
- knockout (4)
- ecstore (4)
- css3 (1)
- 微信 (2)
- dede (0)
- soa_edi (1)
- odoo (0)
- web (1)
最新评论
-
骑着蜗牛超F1:
在ie6下报了个stack overflow at line ...
兼容ie6和ie7 的16进制码流在html中显示为图片代码(base64) -
冰之海洋:
好像少了一句代码吧? FloatingFunc.show(th ...
android 一直在最前面的浮动窗口效果 -
yanzhoupuzhang:
连接有问题!
iis7.0官方下载 IIS 7.0(微软Web服务器组件IIS 7.0) 官方(windows 2003,XP,2000) -
whatable:
唉,楼主你都没有搞清楚重量级和轻量级。。。。既然引用了SWT, ...
java swing 内置浏览器打开网页显示flash图表-swt Browser应用 -
yy_owen:
我晕啊,你链接的什么内容额,我要的iis,你链接个视频什么意思 ...
iis7.0官方下载 IIS 7.0(微软Web服务器组件IIS 7.0) 官方(windows 2003,XP,2000)
导入项目
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //初始化 CameraManager CameraManager.init(getApplication()); viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view); txtResult = (TextView) findViewById(R.id.txtResult); hasSurface = false; inactivityTimer = new InactivityTimer(this); }
打开Eclipse 导入 源码中的 Android 项目,然后右击项目 选择“Build path”——》"Add External Archives" 把核心库 core.jar文件加入到项目中。
此时编译一下项目,会发现报错,“ Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute? ”之类的。打开raw 下的Values 发现错误是在一个<String>上。这里把 “preferences_custom_product_search_summary ” 里的 %s %f 全部都改成 %1$s %1$f(因为我们用不到多国语言,建议只保留默认的Value ,其他全部删除)。
原因:由于新的SDK采用了新版本的aapt(Android项目编译器),这个版本的aapt编译起来会比老版本更加的严格,然后在Android最新的开发文档的描述String的部分,已经说明如何去设置 %s 等符号
“If you need to format your strings using String.format(String, Object...) , then you can do so by putting your format arguments in the string resource. For example, with the following resource:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
In this example, the format string has two arguments: %1$s is a string and %2$d is a decimal number. You can format the string with arguements from your application...“
经过以上步骤后项目应该就可以运行了。
但是ZXing的android项目东西太多了,有很多是我们不需要的,得新建另一个项目简化它。
简化
在开始前大致介绍一下简化ZXing需要用到各个包 、类的职责。
- CaptureActivity。这个是启动Activity 也就是扫描器(如果是第一安装,它还会跳转到帮助界面)。
- CaptureActivityHandler 解码处理类,负责调用另外的线程进行解码。
- DecodeThread 解码的线程。
- com.google.zxing.client.android.camera 包,摄像头控制包。
- ViewfinderView 自定义的View,就是我们看见的拍摄时中间的框框了。
新建另一个项目
新建另一个项目将启动的Activity命名为CaptureActivity,并导入核心库。项目新建完成后我们打开 CaptureActivity 的布局文件,我这里为main。把里面的XML修改为:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <SurfaceView android:id="@+id/preview_view" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerInParent="true" /> <com.Zxing.Demo.view.ViewfinderView android:id="@+id/viewfinder_view" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/transparent" /> <TextView android:layout_width="wrap_content" android:id="@+id/txtResult" android:layout_height="wrap_content" android:text="@string/hello" /> </FrameLayout>
可以看到在XML里面用到了 ViewfinderView 自定义view 。所以新建一个View 的包,然后把:ViewfinderView 和 ViewfinderResultPointCallback 靠到里面(记得对应修改XML里面的包)。
打开 CaptureActivity 覆盖 onCreate 方法:
这里调用到的 CameraManager 类是控制摄像头的包里的类。新建一个camera包把:com.google.zxing.client.android.camera 里面的类全部拷入,另外我把PlanarYUVLuminanceSource也拷入到这个包里面。根据错误的提示来修正代码,主要是修改正包结构。(整 个简化的流程都是如此:“根据错误提示,修改代码 ”)。
在修改的过程中,有很多是关于R 资源的问题,在此我们需要将Values 里面的两个xml资源文件拷入项目中:colos.xml 和ids.xml 。 ctrl+b 一下看看error 是不是少了很多。在CameraManager中有些地方需要用到项目的配置,这里需要把配置直接写入代码中:
/ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); //是否使用前灯 // if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false)) { // FlashlightManager.enableFlashlight(); // } FlashlightManager.enableFlashlight();
使用摄像头需要加入相应的权限:
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
当View 和 camera 包里的错误修正完成后,我们继续来看CaptureActivity。
覆盖onResume方法初始化摄像头:
@Override protected void onResume() { super.onResume(); SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view); SurfaceHolder surfaceHolder = surfaceView.getHolder(); if (hasSurface) { initCamera(surfaceHolder); } else { surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } decodeFormats = null; characterSet = null; playBeep = true; AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE); if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) { playBeep = false; } initBeepSound(); vibrate = true; }
initCamera
private void initCamera(SurfaceHolder surfaceHolder) { try { CameraManager.get().openDriver(surfaceHolder); } catch (IOException ioe) { return; } catch (RuntimeException e) { return; } if (handler == null) { handler = new CaptureActivityHandler(this, decodeFormats, characterSet); } }
@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { if (!hasSurface) { hasSurface = true; initCamera(holder); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { hasSurface = false; }
initCamera () 方法用于初始化摄像头,如果排除了所有的error ,运行项目时就可以看到大致扫描界面了。 surfaceHolder.addCallback( this );表示让CaptureActivity实现其callback接口。
handler = new CaptureActivityHandler(this, decodeFormats, characterSet) 用于进行扫描解码处理。
解码
上面的步骤主要都是用于对摄像头的控制,而解码的真正工作入口是在CaptureActivityHandler 里面的。新建一个Decoding包把以下文件拷入包中:
- CaptureActivityHandler
- DecodeFormatManager
- DecodeHandler
- DecodeThread
- FinishListener
- InactivityTimer
- Intents http://www.my400800.cn
由于我们的包结构和Zxing 项目的有所不同所以需要注意一下类的可访问性
同样开始ctrl+B 编译一下,然后开始修正错误。
在CaptureActivityHandler 里 把 handleMessage 里的部分方法先注释掉如:“decode_succeeded ”分支,这是解码成功时调用 CaptureActivity 展示解码的结果。
在DecodeThread 类里,修改部分涉及Preference配置的代码:
DecodeThread(CaptureActivity activity, Vector<BarcodeFormat> decodeFormats, String characterSet, ResultPointCallback resultPointCallback) { this.activity = activity; handlerInitLatch = new CountDownLatch(1); hints = new Hashtable<DecodeHintType, Object>(3); // // The prefs can't change while the thread is running, so pick them up once here. // if (decodeFormats == null || decodeFormats.isEmpty()) { // SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); // decodeFormats = new Vector<BarcodeFormat>(); // if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true)) { // decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS); // } // if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true)) { // decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS); // } // if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_DATA_MATRIX, true)) { // decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS); // } // } if (decodeFormats == null || decodeFormats.isEmpty()) { decodeFormats = new Vector<BarcodeFormat>(); decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS); decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS); decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS); } hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats); if (characterSet != null) { hints.put(DecodeHintType.CHARACTER_SET, characterSet); } hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback); }
这里是设置 解码的类型,我们现在默认将所有类型都加入。
错误类型基本上都是:包结构、PreferencesActivity 的配置 、类可访问性的问题。根据错误提示耐心把错误解决。
返回解码结果
还记得在 CaptureActivityHandler 的 messagehandler 里注销掉的Case分支吗?现在CaptureActivity 里实现它。
public void handleDecode(Result obj, Bitmap barcode) { inactivityTimer.onActivity(); viewfinderView.drawResultBitmap(barcode); playBeepSoundAndVibrate(); txtResult.setText(obj.getBarcodeFormat().toString() + ":" + obj.getText()); }
最后
ZXing的简化已基本完成,有几位是可以运行成功的?呵呵。
下面是CaptureActivity的源码:
public class CaptureActivity extends Activity implements Callback { private CaptureActivityHandler handler; private ViewfinderView viewfinderView; private boolean hasSurface; private Vector<BarcodeFormat> decodeFormats; private String characterSet; private TextView txtResult; private InactivityTimer inactivityTimer; private MediaPlayer mediaPlayer; private boolean playBeep; private static final float BEEP_VOLUME = 0.10f; private boolean vibrate; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //初始化 CameraManager CameraManager.init(getApplication()); viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view); txtResult = (TextView) findViewById(R.id.txtResult); hasSurface = false; inactivityTimer = new InactivityTimer(this); } @Override protected void onResume() { super.onResume(); SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view); SurfaceHolder surfaceHolder = surfaceView.getHolder(); if (hasSurface) { initCamera(surfaceHolder); } else { surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } decodeFormats = null; characterSet = null; playBeep = true; AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE); if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) { playBeep = false; } initBeepSound(); vibrate = true; } @Override protected void onPause() { super.onPause(); if (handler != null) { handler.quitSynchronously(); handler = null; } CameraManager.get().closeDriver(); } @Override protected void onDestroy() { inactivityTimer.shutdown(); super.onDestroy(); } private void initCamera(SurfaceHolder surfaceHolder) { try { CameraManager.get().openDriver(surfaceHolder); } catch (IOException ioe) { return; } catch (RuntimeException e) { return; } if (handler == null) { handler = new CaptureActivityHandler(this, decodeFormats, characterSet); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { if (!hasSurface) { hasSurface = true; initCamera(holder); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { hasSurface = false; } public ViewfinderView getViewfinderView() { return viewfinderView; } public Handler getHandler() { return handler; } public void drawViewfinder() { viewfinderView.drawViewfinder(); } public void handleDecode(Result obj, Bitmap barcode) { inactivityTimer.onActivity(); viewfinderView.drawResultBitmap(barcode); playBeepSoundAndVibrate(); txtResult.setText(obj.getBarcodeFormat().toString() + ":" + obj.getText()); } private void initBeepSound() { if (playBeep && mediaPlayer == null) { // The volume on STREAM_SYSTEM is not adjustable, and users found it // too loud, // so we now play on the music stream. setVolumeControlStream(AudioManager.STREAM_MUSIC); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setOnCompletionListener(beepListener); AssetFileDescriptor file = getResources().openRawResourceFd( R.raw.beep); try { mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength()); file.close(); mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME); mediaPlayer.prepare(); } catch (IOException e) { mediaPlayer = null; } } } private static final long VIBRATE_DURATION = 200L; private void playBeepSoundAndVibrate() { if (playBeep && mediaPlayer != null) { mediaPlayer.start(); } if (vibrate) { Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); vibrator.vibrate(VIBRATE_DURATION); } } /** * When the beep has finished playing, rewind to queue up another one. */ private final OnCompletionListener beepListener = new OnCompletionListener() { public void onCompletion(MediaPlayer mediaPlayer) { mediaPlayer.seekTo(0); } };
简化过的包结构图:
简化后的ZXing 更加方便我们了解ZXing项目 是如何解码的。只要仔细查看源码,进行单点跟踪调试,相信大家很容易能理解。
发表评论
-
andorid eclipse断点调试失灵
2013-05-09 15:06 1387在调试android程序的时候发现设置的断点怎么也进不去 ... -
Android使用ZXing类库进行条码/二维码识别
2011-12-26 11:24 1885Android使用ZXing类库进行条码/二维码识别(转) ... -
如何在开发时可以让Android应用程序支持安装到SD卡
2011-12-16 08:51 1014Android系统在2.1版本之前,应用程序是只能安装到机身内 ... -
用TextView显示带图片的效果及为文本添加链接
2011-12-06 17:13 1865为了实现在TextView中显示图片,有时对图片的宽度与高度有 ... -
android listview 滚动时异步加载图片的问题
2011-12-05 15:05 2426LoadImage.java package com ... -
android apk 为程序增加代码混淆
2011-11-30 10:09 2726概述 在2.3版本的sdk中可以看到在ANDROID_S ... -
Android 程序的安装、卸载和更新
2011-11-22 11:20 1252安装程序:软件从无到有。 卸载程序:软件从有到无。 ... -
atest201111
2011-11-21 17:04 0eeeee SQLite Developer ... -
android-XXX9.png文件拉伸不失真大家注意了
2011-11-17 14:24 1816什么是9.png: 可能做过任务栏美化 ... -
Android中String资源文件的String.format方法(java)
2011-10-25 16:57 1302很多时候我们感性Google ... -
android 一直在最前面的浮动窗口效果
2011-10-21 15:51 15990今天发现一些软件可以 ... -
Android 对于ListView拖动时变黑问题解决方法
2011-10-21 13:08 1602最近用ListView显示一些String数据 ... -
Android SeekBarPreference浅聊
2011-10-19 15:37 1593由于网上有很多人问到SeekBarPreferenc ... -
在Android中创建启动界面
2011-10-14 09:06 8311、制作一张启动图片splash.png,放置在res ... -
Android 菜单(OptionMenu)大全 建立你自己的菜单
2011-10-13 09:11 744菜单是用户界面中最常见的元素之一,使用非常频繁,在Andro ... -
Android中使用Gson解析JSON数据
2011-10-12 13:33 1618在Android中可以使用Gson解析JSON数据 ... -
android解析json小例子
2011-10-12 12:53 1175今天学习了一下解析json的知识,把我学习的的一个小例子拿出来 ... -
解决android http请求带中文参数会乱码(url编码)
2011-09-29 17:23 3289今天在用android 的 URL url = new U ... -
android 选择本地图片并预览
2011-09-29 14:40 1288adv_sdcard_image_upload.xml ... -
关于 apk文件反编译的方法(dex2jar和JD-GUI)
2011-09-19 11:51 1658觉着这2个工具配合学习android太靠谱了,所以放上来给大家 ...
相关推荐
在Android开发中,ZXing(Zebra Crossing)库是一个广泛使用的开源项目,它提供了二维码和条形码的生成与扫描功能。ZXing库为开发者提供了一个便捷的方式,将二维码扫描集成到自己的应用中,无需从零开始实现这些...
本篇文章将详细探讨如何利用AutoJS调用ZXing库来实现条形码和二维码的扫描功能。 首先,ZXing(Zebra Crossing)是一个开源的、跨平台的条形码和二维码读取库。它支持多种编码格式,如QR码、Data Matrix、UPC、EAN...
在Android开发中,二维码扫描是一项常见的功能,用于读取和生成包含信息的二维条形码。ZXing(Zebra Crossing)是Google开发的一个开源项目,它提供了跨平台的二维码和条形码处理库。本文将详细介绍如何在Android...
《Zxing:打造高效能的条形码与二维码扫描应用》 Zxing,全称“ZXing,意为“zebra crossing”(斑马线),是一个开源的、跨平台的条形码和二维码读取库。它允许开发者轻松地集成条码和二维码扫描功能到他们的应用...
《Android Zxing条码扫描源码解析》 在Android应用开发中,Zxing(又称为ZXing,意为“快速可扩展的二进制解码”)是一个强大的开源项目,专注于各种类型的条码扫描和生成。它提供了跨平台的库,使得开发者能够轻松...
下面将详细阐述ZXing的工作原理以及如何利用其开发一个完整的条形码、二维码生成与扫描的Demo。 首先,让我们了解一下条形码和二维码。条形码是一种用黑白相间的条纹表示数字和字母的信息编码方式,通常包括UPC...
总之,ZXing是一个强大的条形码和二维码处理工具,通过这个修改后的源码,开发者可以更灵活地在Android项目中应用条形码和二维码功能,而无需担心原生包名带来的问题。只需遵循正确的集成步骤,并结合项目需求进行...
1. **ZXing (Zebra Crossing)**: ZXing是一个开源的、多平台的一维和二维条码图像处理库,支持多种格式的编码和解码,如QR码、条形码等。在Android平台上,ZXing常用于实现二维码扫描功能。 2. **在Delphi XE10中...
总之,Google ZXing提供的源码Demo是一个宝贵的教育资源,可以帮助开发者深入了解条形码和二维码的生成与扫描原理,以及如何在实际项目中高效地利用ZXing库。通过深入研究这个源码,你不仅可以掌握ZXing的基本用法,...
总之,基于Google Zxing在Android上实现二维码和条形码扫描涉及了Android的摄像头操作、图像处理、UI设计等多个方面。通过合理的代码结构和用户体验设计,我们可以构建出一个高效且易用的扫描应用,类似微信的扫描...
ZXing,全称为“Zebra Crossing”,是一款开源的、跨平台的条形码和二维码读取库。在Android平台上,ZXing(又称“二维码扫一扫”)被广泛用于实现二维码扫描功能。本文将深入探讨ZXing源码,解析其在Android应用中...
本项目"Android 基于google Zxing实现二维码、条形码扫描"就是这样一个示例,它旨在模仿微信的二维码扫描体验,让用户能够快速、方便地读取和识别二维码或条形码信息。 Zxing,又称为“二维码解码器”,是由Google...
ZXing(Zebra Crossing),又称“条形码解码库”,是一个开源项目,提供了多种格式的一维和二维条码读取功能,包括二维码。本篇文章将深入探讨如何使用ZXing来识别一幅包含多个二维码的图片。 首先,我们需要理解...
本篇将深入解析"android 扫描二维码源码及实例"中的关键知识点,包括二维码的基本原理、Android二维码库的使用、相机权限处理以及用户界面设计。 首先,我们需要了解二维码的基本概念。二维码(Quick Response Code...
【Zxing二维码条形码跨平台源码】是一款基于C++语言开发的开源项目,它允许开发者在不同的操作系统上,包括手机(Android、iOS)、Windows系统等,实现二维码和条形码的扫描与生成功能。这个项目的核心是Zxing...
二维码(Quick Response Code,简称QR码)是一种二维条形码,可以存储丰富的信息,如网址、文本、联系人信息等。ZXing(Zebra Crossing)是Google开发的一个开源的、跨平台的条码读取库,支持多种类型的条码和二维码...
在Android开发中,集成二维码和条形码扫描是一项常见的需求,而Zxing(又名ZXing,意为“zebra crossing”,斑马线)是一个开源的、跨平台的条码图像处理库,提供了多种格式的一维和二维条码的生成与扫描功能。...
在Android开发中,ZXing(Zebra Crossing)库是一个广泛使用的开源项目,它提供了二维码和条形码的生成与扫描功能。ZXing库为开发者提供了便捷的API接口,使得在Android应用中集成二维码扫描和生成变得简单易行。...
对于标题中提到的"可以编译的二维码、条形码扫描源码",这意味着你可以直接获取到ZXing的源代码,并根据自己的需求进行定制和编译。这对于开发者来说是非常有价值的,因为可以深入理解其内部工作原理,同时也能够...
在Android开发中,ZXing(Zebra Crossing)库是一个广泛使用的开源项目,它提供了解析和生成条形码和二维码的能力。本项目是关于如何在Android应用中简单地集成ZXing来实现条码和二维码的识别功能。下面将详细介绍这...