十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
在苹果手机自带的应用里,包括相机,是没有扫描二维码这个功能的。但是可以采取其他手段如下:
创新互联建站坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、成都网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的东胜网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
1、QQ、微信、微博这一类软件,它们就有扫描二维码的功能,支持用手机上的相机直接扫描二维码,也支持扫描你保存到手机相册中的二维码。
2、这里以微信为例,打开以后点击屏幕右上角的 + 按钮,如图所示
3、接下来打开微信里的“扫一扫”功能,如图所示
4、随后将手机相机对准二维码,让它显示在屏幕的框内,即可扫描了。
开源的二维码扫描库主要有zxing和zbar,zbar在iPos平台上应用比较成熟,而在Android平台上主流还是用zxing库,因此这里主要讲述如何利用zxing进行二维码开发。
如何将zxing的Android源码导入工程。
在导入zxing的android源码之前,先去官方下载zxing的源码。
这里以1.6版本为例,zxing 1.6源码结构如下:
其中android文件夹就是android平台下的官方例子,在导入之前先要对core文件下的源码进行编译,得到核心包core.jar。
编译方法请参照:
然后就可以导入android平台下的例子了,导入方法如下:
打开Eclipse,新建android项目:(注意不要直接把android文件夹拷到workspace下导入,那样会无法导入)
导入核心包core.jar。
修改strings.xml文件。在导入core.jar之后工程还是会有下面的错误,出现这种错误可能是由于字符错误导致的,只需要把所有的%s 和%f改成 %1s和f 即可
修改完之后重新清理项目,此时已经没有错误了
将zxing代码嵌入自己的工程
在自己的工程中嵌入简化的zxing代码即可实现二维码生成和识别功能
嵌入方法:
将上述简化的代码拖到自己工程目录下;
将values文件夹和raw文件夹复制自己工程目录下;
建立CaptureActivity.java的布局文件capture.xml:
?xml version="1.0" encoding="utf-8"?
FrameLayout xmlns:android=""
android:layout_width="fill_parent"
android:layout_height="fill_parent"
SurfaceView
android:id="@+id/preview_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" /
com.zxing.view.ViewfinderView
android:id="@+id/viewfinder_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /
RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:orientation="vertical"
TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:gravity="center"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="Scan Barcode"
android:textColor="@android:color/white"
android:textSize="18sp"
android:textStyle="bold" /
Button
android:id="@+id/btn_cancel_scan"
android:layout_width="230dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_marginBottom="75dp"
android:text="Cancel"
android:textSize="15sp"
android:textStyle="bold" /
/RelativeLayout
/FrameLayout
导入core.jar包
修改AndrodMainfest.xml
?xml version="1.0" encoding="utf-8"?
manifest xmlns:android=""
package="com.qrcode"
android:versionCode="1"
android:versionName="1.0"
uses-sdk android:minSdkVersion="7" /
uses-permission android:name="android.permission.VIBRATE" / !-- 震动权限 --
uses-permission android:name="android.permission.CAMERA" /
uses-feature android:name="android.hardware.camera" / !-- 使用照相机权限 --
uses-feature android:name="android.hardware.camera.autofocus" / !-- 自动聚焦权限 --
application android:icon="@drawable/icon" android:label="@string/app_name"
activity android:name=".MainActivity"
android:label="@string/app_name"
intent-filter
action android:name="android.intent.action.MAIN" /
category android:name="android.intent.category.LAUNCHER" /
/intent-filter
/activity
!-- 隐藏键盘 --!-- 全屏 --
activity
android:configChanges="orientation|keyboardHidden"
android:name="com.zxing.activity.CaptureActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden"
/activity
/application
/manifest
这种情况大致就可以实现二维码扫描了,想细化的话,还可以多看看安卓二维码扫描开发相关的教程
首先看一下扫描界面
CaptureCodeActivity.java代码:
package com.haier.qr.code;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import java.util.Vector;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Result;
import com.haier.cabinet.customer.R;
import com.haier.cabinet.customer.activity.DeliveryBoxListActivity;
import com.haier.common.util.AppToast;
import com.haier.qr.code.zxing.camera.CameraManager;
import com.haier.qr.code.zxing.decoding.CaptureActivityHandler;
import com.haier.qr.code.zxing.decoding.FinishListener;
import com.haier.qr.code.zxing.decoding.InactivityTimer;
import com.haier.qr.code.zxing.view.ViewfinderView;
/**
* Initial the camera
*
* @author jdsjlzx
*/
public class CaptureCodeActivity extends Activity implements Callback,View.OnClickListener {
private static final String TAG = CaptureCodeActivity.class
.getSimpleName();
private CameraManager cameraManager;
private CaptureActivityHandler handler;
private ViewfinderView viewfinderView;
private boolean hasSurface;
private MapDecodeHintType, ? decodeHints;
private VectorBarcodeFormat decodeFormats;
private String characterSet;
private InactivityTimer inactivityTimer;
private boolean isFlashlightOpen;
/**
* 声音震动管理器。如果扫描成功后可以播放一段音频,也可以震动提醒,可以通过配置来决定扫描成功后的行为。
*/
private BeepManager beepManager;
/**
* 闪光灯调节器。自动检测环境光线强弱并决定是否开启闪光灯
*/
private AmbientLightManager ambientLightManager;
public CameraManager getCameraManager() {
return cameraManager;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_capture);
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
beepManager = new BeepManager(this);
ambientLightManager = new AmbientLightManager(this);
//按钮监听事件
findViewById(R.id.capture_flashlight).setOnClickListener(this);
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
viewfinderView.setVisibility(View.VISIBLE);
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
initCamera(surfaceHolder);
} else {
// 防止sdk8的设备初始化预览异常
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Install the callback and wait for surfaceCreated() to init the
// camera.
surfaceHolder.addCallback(this);
}
decodeFormats = null;
characterSet = null;
// 加载声音配置,其实在BeemManager的构造器中也会调用该方法,即在onCreate的时候会调用一次
beepManager.updatePrefs();
// 启动闪光灯调节器
ambientLightManager.start(cameraManager);
// 恢复活动监控器
inactivityTimer.onResume();
}
@Override
protected void onPause() {
Log.d(TAG, "onPause");
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
inactivityTimer.onPause();
ambientLightManager.stop();
beepManager.close();
// 关闭摄像头
cameraManager.closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
/**
* A valid barcode has been found, so give an indication of success and show
* the results.
*
* @param rawResult
* The contents of the barcode.
* @param scaleFactor
* amount by which thumbnail was scaled
* @param barcode
* A greyscale bitmap of the camera data which was decoded.
*/
public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
Log.d(TAG, "handleDecode");
inactivityTimer.onActivity();
beepManager.playBeepSoundAndVibrate();
String resultString = rawResult.getText();
if (TextUtils.isEmpty(resultString)) {
Toast.makeText(CaptureCodeActivity.this, "Scan failed!",
Toast.LENGTH_SHORT).show();
} else {
//扫码完成,处理结果(跳转到箱子列表)
/*Intent resultIntent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("result", resultString);
bundle.putParcelable("bitmap", barcode);
resultIntent.putExtras(bundle);
this.setResult(RESULT_OK, resultIntent);*/
String terminalNo = getIntent().getStringExtra("terminal_no");
if (resultString.equals(terminalNo)) {
AppToast.makeToast(this, "确认成功!");
Intent intent = new Intent(this, DeliveryBoxListActivity.class);
intent.putExtra("terminal_no", terminalNo);
intent.putExtra("box_list", (Serializable) getIntent().getSerializableExtra("box_list"));
startActivity(intent);
CaptureCodeActivity.this.finish();
} else {
/*AppToast.makeToast(this, "确认失败,请重新扫描确认");*/
showErrorDialog();
}
}
}
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
Log.w(TAG,
"initCamera() while already open -- late SurfaceView callback?");
return;
}
try {
cameraManager.openDriver(surfaceHolder);
// Creating the handler starts the preview, which can also throw a
// RuntimeException.
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats,
decodeHints, characterSet, cameraManager);
}
} catch (IOException ioe) {
Log.w(TAG, ioe);
displayFrameworkBugMessageAndExit();
} catch (RuntimeException e) {
// Barcode Scanner has seen crashes in the wild of this variety:
// java.?lang.?RuntimeException: Fail to connect to camera service
Log.w(TAG, "Unexpected error initializing camera", e);
displayFrameworkBugMessageAndExit();
}
}
private void displayFrameworkBugMessageAndExit() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage(getString(R.string.msg_camera_framework_bug));
builder.setPositiveButton(android.R.string.yes, new FinishListener(this));
builder.setOnCancelListener(new FinishListener(this));
builder.show();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(TAG,
"*** WARNING *** surfaceCreated() gave us a null surface!");
}
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();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.capture_flashlight:
if (isFlashlightOpen) {
cameraManager.setTorch(false); // 关闭闪光灯
isFlashlightOpen = false;
}
else {
cameraManager.setTorch(true); // 打开闪光灯
isFlashlightOpen = true;
}
break;
default:
break;
}
}
private void showErrorDialog() {
closeCamera();
viewfinderView.setVisibility(View.GONE);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage("扫描确认出错,请重新扫描二维码!");
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
restartCamera();
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
CaptureCodeActivity.this.finish();
}
});
builder.show();
}
void restartCamera(){
Log.d(TAG, "hasSurface " + hasSurface);
viewfinderView.setVisibility(View.VISIBLE);
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
initCamera(surfaceHolder);
// 恢复活动监控器
inactivityTimer.onResume();
}
void closeCamera(){
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
inactivityTimer.onPause();
// 关闭摄像头
cameraManager.closeDriver();
}
}
在扫描出现问题事弹出dialog,当用户点击确定按钮后重新开始扫描。
private void showErrorDialog() {
closeCamera();
viewfinderView.setVisibility(View.GONE);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage("扫描确认出错,请重新扫描柜子上的二维码!");
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
restartCamera();
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
CaptureCodeActivity.this.finish();
}
});
builder.show();
}
先打开本地下载,复制文件,拷贝到他们的项目中即可。
首先我们打开google的zxing的地址,googledezxing地址(本地下载),打开之后我们会看到界面,将这个文件下载我们本地,下载好之后我们需要复制android文件下的几个类,根据这些类名称在android文件下找到这些类,拷贝到他们的项目中,拷贝之后会有报错,我们需要将android文件下的res中的文件也拷贝到我们的项目中。完成之后我们还要依赖zxing的核心类库,当我们的项目不报错的时候,就可以先实现扫描二维码和生成二维码。
二维码用某种特定几何图形按定规律平面(二维向)布黑白相间图形记录数据符号信息代码编制巧妙利用构计算机内部逻辑基础0、1比特流概念使用若干与二进制相应几何形体表示文字数值信息通图象输入设备或光电扫描设备自识读实现信息自处理:
二维条码
/
二维码能够横向纵向两位同表达信息能面积内表达量信息二维码何使用我见
Android
应用使用二维码载前提
Android
手机要装扫描(或识别)二维码软件Android平台见手机码工具快拍(Quick拍)或条码扫描器(Barcode
Scanner)我快拍例安装快拍二维码扫描工具打该软件:打快拍二维码扫描工具准网站二维码:稍等片刻快拍自识别并扫描该
二维码址:扫描完整快拍显示该二维码信息1处二维码信息2号二维码扫描结
apk
文件址点击3号进行载:至快拍已经完使命(使用二维码):识别二维码并载址栏步
apk
文件址载完安装即
你好!具体的我不懂怎么讲,就相当于商品的身份证,二维码不容易仿冒。你看看下面的介绍吧。。。网路找到的。
什么是条码技术?
条形码,简称“条码”,是由一组黑白相间、宽度不同的条状符号组成。
条码技术是研究如何把计算机所需要的数据表示成条码形式,和如何将条码表示的数据和符号转变为计算机可以自动采集、识别的数据。因而,条码技术就包括从编码到制作、识读、处理等一系列技术。
根据不同的编码规则,提出的编码方案已经有多达四十余种,目前应用最为广泛的有:交叉二五码、三九码、UPC码、EAN码、128码等。
从印制条形码的材料、颜色分类,可分黑白条形码、彩色条形码、发光条形码(荧光条形码、磷光条形码)和磁性条形码等。
近年来又出现了按矩阵方式或堆栈方式排列信息的二维条形码。
我国的适用标准:一维条码通用商品条码是与EAN码等效,二维条码是与PDF417兼容的码制。
条形码有什么优点?
A.输入速度快:与键盘输入相比,条码输入的速度是键盘输入的5倍,并且能实现"即时数据输入"。
B.可靠性高:键盘输入数据出错率为三百分之一,利用光学字符识别技术出错率为万分之一,而采用条码技术误码率低于百万分之一。
C.采集信息量大:利用传统的一维条码一次可采集几十位字符的信息,二维条码更可以携带数千个字符的信息,并有一定的自动纠错能力。
D.灵活实用:条码标识既可以作为一种识别手段单独使用,也可以和有关识别设备组成一个系统实现自动化识别,还可以和其他控制设备联接起来实现自动化管理。
另外,条码标签易于制作,对设备和材料没有特殊要求,识别设备操作容易,不需要特殊培训,且设备也相对便宜。
条形码的应用领域
仓库管理系统(商品、库位标识)
在工业中的应用(零部件标识,过程控制,信息传递等)
办公室自动化管理(固定资产管理,门卫、考勤管理等)
还可以用于如,图书管理、商场管理、血库管理、邮电管理、海关报关单管理等等。
一维条码的结构与组成
我国采用的一维条码是通用商品条码,采用EAN条码结构。EAN条码是国际上通用的通用商品代码。我国主版是由13位数字及相应的条码符号组成,在较小的商品上也采用8位数字码及其相应的条码符号。
每个条码的组成可分为:
1.前缀码。由三位数字组成,是国家的代码,我国为690,是国际物品编码会统一决定的。
2.制造厂商代码。由四位数字组成,我国物品编码中心统一分配并统一注册,一厂一码。
3商品代码。由五位数字组成,表示每个制造厂商的商品,由厂商确定,可标识十万种商品。
4.校验码。由一位数字组成,用以校验前面各码的正误。
一维条码的特点
条形码符号图形结构简单;
每个条形码字符由一定的条符组成,占有一定的宽度和印制面积;
每种编码方案均有自己的字符集;
每种编码方案与对应的阅读装置的性能要求密切配合。一维条码的容量多数一维条码所能表示的字符集不过是10个数字,26个英文字母及一些特殊字符。条码字符集最大的Code l28条码,所能表示的字符个数也不过是128个ASCII符。什么是二维条码?二维条码能够在横向和纵向两个方位同时表达信息,因此能在很小的面积内表达大量的信息。二维条码可以分为堆叠式二维条码和矩阵式二维条码。堆叠式二维条码形态上是由多行短截的一维条码堆叠而成;矩阵式二维条码以矩阵的形式组成,在矩阵相应元素位置上用“点”表示二进制“1”,用“空”表示二进制“0”,由“点”和“空”的排列组成代码。堆叠式二维条码,有代表性的包括PDF417、Code 49、Code 16K等。矩阵式二维条码有代表性的是Code one、Aztec、Date Matrix、QR码等。二维条码的特点1.高密度编码,信息容量大:可容纳多达1850个大写字母或2710个数字或1108个字节,或500多个汉字,比普通条码信息容量约高几十倍。2.编码范围广:该条码可以把图片、声音、文字、签字、指纹等可以数字化的信息进行编码,用条码表示出来;可以表示多种语言文字;可表示图像数据。3.容错能力强,具有纠错功能:这使得二维条码因穿孔、污损等引起局部损坏时,照样可以正确得到识读,损毁面积达50%仍可恢复信息。4.译码可靠性高:它比普通条码译码错误率百万分之二要低得多,误码率不超过千万分之一。5.可引入加密措施:保密性、防伪性好6.成本低,易制作,持久耐用7.条码符号形状、尺寸大小比例可变8.二维条码可以使用激光或CCD阅读器识读。