android二維碼靈敏
A. androidapp二維碼掃碼下載,途牛網站的效果,怎麼實現
Android 二維碼掃描是很常用的工具,是不是很Cool,到底如何實現的呢,下面我們就來探討一下Zxing的實現方法(底部附上下載鏈接):
首先
工程結構:
如何引用:(內容來自雪炭網SnowCoal.com)
一般來說,你就可以改改就用了,但如果你只想把它當成一個小小的子集加入項目,你需要將三個包Copy至你的項目中:(camera、decoding、view),然後引入相對應的資源進去,不要訪記還有一個Jar包哦!(Zxing.jar)
關於布局:
com.example.qr_codescan包裡面有一個MipcaActivityCapture,也是直接引入,這個Activity主要處理掃描界面的類,比如,掃描成功有聲音和振動等等,主要關注裡面的handleDecode(Result
result, Bitmap barcode)方法,掃描完成之後將掃描到的結果和二維碼的bitmap當初參數傳遞到handleDecode(Result
result, Bitmap barcode)裡面,我們只需要在裡面寫出相對應的處理代碼即可,其他的地方都不用改得,這里處理掃描結果和掃描拍的照片.
* 處理掃描結果
* @param result
* @param barcode
*/
public void handleDecode(Result result, Bitmap barcode) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
String resultString = result.getText();
if (resultString.equals( "" )) {
Toast.makeText(MipcaActivityCapture. 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);
}
MipcaActivityCapture. this .finish();
}
對MipcaActivityCapture界面的布局做了自己的改動,先看下效果圖,主要是用到FrameLayout,裡面嵌套RelativeLayout。
//xml
android:layout_width= "fill_parent"
android:layout_height= "fill_parent" >
android:layout_width= "fill_parent"
android:layout_height= "fill_parent" >
android:id= "@+id/preview_view"
android:layout_width= "fill_parent"
android:layout_height= "fill_parent"
android:layout_gravity= "center" />
android:id= "@+id/viewfinder_view"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content" />
< include
android:id= "@+id/include1"
android:layout_width= "fill_parent"
android:layout_height= "wrap_content"
android:layout_alignParentTop= "true"
layout= "@layout/activity_title" />
實現:
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
private final static int SCANNIN_GREQUEST_CODE = 1 ;
/**
* 顯示掃描結果
*/
private TextView mTextView ;
/**
* 顯示掃描拍的圖片
*/
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.result);
mImageView = (ImageView) findViewById(R.id.qrcode_bitmap);
//點擊按鈕跳轉到二維碼掃描界面,這里用的是startActivityForResult跳轉
//掃描完了之後調到該界面
Button mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity. this , MipcaActivityCapture. class );
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivityForResult(intent, SCANNIN_GREQUEST_CODE);
}
});
}
@Override
protected void onActivityResult( int requestCode, int resultCode, Intent
data) {
super .onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SCANNIN_GREQUEST_CODE:
if (resultCode == RESULT_OK){
Bundle bundle = data.getExtras();
//顯示掃描到的內容
mTextView.setText(bundle.getString( "result" ));
//顯示
mImageView.setImageBitmap((Bitmap) data.getParcelableExtra( "bitmap"
));
}
break ;
}
}
}
B. Android開發時APP下載安裝後,第一次掃描二維碼慢正常嗎
不正常!掃碼跟第一次第二次沒關系吧
C. 在android開發中 什麼庫可以識別DM二維碼
1.1 准備工作
如果我們只做二維碼的生成,那麼只需要添加核心jar包即可,
1.2 二維碼生成
OK,添加完jar包之後我們就可以開始寫二維碼生成代碼了,二維碼本身就是一張Bitmap圖片,所以我們這里主要就是看怎麼樣來生成這張圖片,我在主界面添加一個按鈕和一個ImageView,當點擊按鈕時生成一張二維碼圖片顯示在ImageView上。布局如下:
[java] view plain print?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.mobiletrain.qrwriter.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="generate"
android:text="生成二維碼"/>
<ImageView
android:id="@+id/iv"
android:layout_width="256dp"
android:layout_height="256dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
當我點擊按鈕時生成二維碼圖片,那我們就來看看生成二維碼圖片的核心代碼:
[java] view plain print?
private Bitmap generateBitmap(String content,int width, int height) {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<EncodeHintType, String> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
try {
BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
int[] pixels = new int[width * height];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (encode.get(j, i)) {
pixels[i * width + j] = 0x00000000;
} else {
pixels[i * width + j] = 0xffffffff;
}
}
}
return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.RGB_565);
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
首先這個方法接收三個參數,這三個參數分別表示生成二維碼的文本內容(你要把哪一個文本用二維碼圖片表示出來),第二個和第三個參數分別表示生成的二維碼圖片的寬和高。在這里,我們首先要獲得一個QRCodeWriter實例,該實例中有一個方法叫做encode,通過該方法對文本內容進行編碼,該方法共有五個參數,第一個參數表示生成二維碼的文本內容,第二個參數表示編碼格式,第三個參數表示生成的二維碼的寬度,第四個參數表示生成的二維碼的高度,第五個參數可選,可以用來設置文本的編碼,encode方法的返回值是一個BitMatrix,你可以把BitMatrix理解成一個二維數組,這個二維數組的每一個元素都表示一個像素點是否有數據。OK,接下來我們需要定義一個int數組用來存放Bitmap中所有像素點的顏色,可是我們又怎麼知道每一個像素點是什麼顏色呢?這個時候就需要我們遍歷BitMatrix了,如果BitMatrix上的點表示 該點有數據,那麼對應在Bitmap上的像素點就是黑色,否則就是白色。BitMatrix中的get方法的返回值為一個boolean類型,true表示該點有數據,false表示該點沒有數據。通過兩個嵌套的for循環將BitMatrix遍歷一遍,然後給pixels數組都賦上值,OK,pixels數組有值之後,接下來調用Bitmap的createBitmap方法創建一個Bitmap出來就可以了,createBitmap方法共接收6個參數,第一個參數表示Bitmap中所有像素點的顏色,第二個參數表示像素點的偏移量,第三個參數表示Bitmap每行有多少個像素點,第四個參數表示生成的Bitmap的寬度,第五個參數表示生成的Bitmap的高度,第六個參數表示生成的Bitmap的色彩模式,因為二維碼只有黑白兩種顏色,所以我們可以不用考慮透明度,直接使用RGB_565即可。OK,這樣的話我們就獲取到了二維碼的圖片了,最後我們再來看看點擊事件:
[java] view plain print?
public void generate(View view) {
Bitmap qrBitmap = generateBitmap("http://www.csdn.net",400, 400);
iv.setImageBitmap(qrBitmap);
}
D. Android開發時APP下載安裝後,第一次掃描二維碼慢正常嗎
1.
首先需要一個中間頁面,判斷是什麼系統的設備掃描
2.
在ios系統設備掃描時
如果是微信掃描,因為第一步里使用了中間頁面,此時無法直接跳轉到app
store了,所以需要給出提示頁面,提示用戶點擊右上角瀏覽器,以打開app
store下載頁面
如果是微信以外的其他app掃描,直接跳轉到app
store下載頁面
3.在android系統設備掃描時
如果是微信掃描
1)
可以跳轉到應用寶下載頁面
2)
或者可以給出提示頁面,提示用戶點擊右上角瀏覽器打開,下載apk
如果是微信以外的其他app掃描,則直接跳轉開始下載apk
在這里,向運營同學們推薦二維碼工房pro。這是目前能支持以上需求的體驗較好的app,還提供了彩碼、邊框、融合二維碼等美化功能。有趣的是,它的中間頁面設計得跟微信的原生頁面差不多,感覺像是微信在提示用戶一樣。不過只能在ios設備上使用。
E. Android 二維碼掃描怎樣實現第二次掃描
首先看一下掃描界面
CaptureCodeActivity.java代碼:
packagecom.haier.qr.code;
importjava.io.IOException;
importjava.io.Serializable;
importjava.util.Map;
importjava.util.Vector;
importandroid.app.Activity;
importandroid.app.AlertDialog;
importandroid.content.DialogInterface;
importandroid.content.DialogInterface.OnCancelListener;
importandroid.content.DialogInterface.OnClickListener;
importandroid.content.Intent;
importandroid.graphics.Bitmap;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.text.TextUtils;
importandroid.util.Log;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceHolder.Callback;
importandroid.view.SurfaceView;
importandroid.view.View;
importandroid.view.Window;
importandroid.view.WindowManager;
importandroid.widget.Toast;
importcom.google.zxing.BarcodeFormat;
importcom.google.zxing.DecodeHintType;
importcom.google.zxing.Result;
importcom.haier.cabinet.customer.R;
importcom.haier.cabinet.customer.activity.DeliveryBoxListActivity;
importcom.haier.common.util.AppToast;
importcom.haier.qr.code.zxing.camera.CameraManager;
importcom.haier.qr.code.zxing.decoding.CaptureActivityHandler;
importcom.haier.qr.code.zxing.decoding.FinishListener;
importcom.haier.qr.code.zxing.decoding.InactivityTimer;
importcom.haier.qr.code.zxing.view.ViewfinderView;
/**
*Initialthecamera
*
*@authorjdsjlzx
*/
,View.OnClickListener{
privatestaticfinalStringTAG=CaptureCodeActivity.class
.getSimpleName();
;
;
;
privatebooleanhasSurface;
privateMap<DecodeHintType,?>decodeHints;
privateVector<BarcodeFormat>decodeFormats;
privateStringcharacterSet;
;
;
/**
*聲音震動管理器。如果掃描成功後可以播放一段音頻,也可以震動提醒,可以通過配置來決定掃描成功後的行為。
*/
privateBeepManagerbeepManager;
/**
*閃光燈調節器。自動檢測環境光線強弱並決定是否開啟閃光燈
*/
;
(){
returncameraManager;
}
/**.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
Windowwindow=getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_capture);
hasSurface=false;
inactivityTimer=newInactivityTimer(this);
beepManager=newBeepManager(this);
ambientLightManager=newAmbientLightManager(this);
//按鈕監聽事件
findViewById(R.id.capture_flashlight).setOnClickListener(this);
}
@Override
protectedvoidonResume(){
super.onResume();
Log.d(TAG,"onResume");
cameraManager=newCameraManager(getApplication());
viewfinderView=(ViewfinderView)findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
viewfinderView.setVisibility(View.VISIBLE);
SurfaceViewsurfaceView=(SurfaceView)findViewById(R.id.preview_view);
SurfaceHoldersurfaceHolder=surfaceView.getHolder();
if(hasSurface){
initCamera(surfaceHolder);
}else{
//防止sdk8的設備初始化預覽異常
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//()toinitthe
//camera.
surfaceHolder.addCallback(this);
}
decodeFormats=null;
characterSet=null;
//載入聲音配置,其實在BeemManager的構造器中也會調用該方法,即在onCreate的時候會調用一次
beepManager.updatePrefs();
//啟動閃光燈調節器
ambientLightManager.start(cameraManager);
//恢復活動監控器
inactivityTimer.onResume();
}
@Override
protectedvoidonPause(){
Log.d(TAG,"onPause");
if(handler!=null){
handler.quitSynchronously();
handler=null;
}
inactivityTimer.onPause();
ambientLightManager.stop();
beepManager.close();
//關閉攝像頭
cameraManager.closeDriver();
if(!hasSurface){
SurfaceViewsurfaceView=(SurfaceView)findViewById(R.id.preview_view);
SurfaceHoldersurfaceHolder=surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
@Override
protectedvoidonDestroy(){
inactivityTimer.shutdown();
super.onDestroy();
}
/**
*Avalidbarcodehasbeenfound,
*theresults.
*
*@paramrawResult
*Thecontentsofthebarcode.
*@paramscaleFactor
*
*@parambarcode
*.
*/
publicvoidhandleDecode(ResultrawResult,Bitmapbarcode,floatscaleFactor){
Log.d(TAG,"handleDecode");
inactivityTimer.onActivity();
beepManager.playBeepSoundAndVibrate();
StringresultString=rawResult.getText();
if(TextUtils.isEmpty(resultString)){
Toast.makeText(CaptureCodeActivity.this,"Scanfailed!",
Toast.LENGTH_SHORT).show();
}else{
//掃碼完成,處理結果(跳轉到箱子列表)
/*IntentresultIntent=newIntent();
Bundlebundle=newBundle();
bundle.putString("result",resultString);
bundle.putParcelable("bitmap",barcode);
resultIntent.putExtras(bundle);
this.setResult(RESULT_OK,resultIntent);*/
StringterminalNo=getIntent().getStringExtra("terminal_no");
if(resultString.equals(terminalNo)){
AppToast.makeToast(this,"確認成功!");
Intentintent=newIntent(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();
}
}
}
privatevoidinitCamera(SurfaceHoldersurfaceHolder){
if(surfaceHolder==null){
thrownewIllegalStateException("NoSurfaceHolderprovided");
}
if(cameraManager.isOpen()){
Log.w(TAG,
"initCamera()whilealreadyopen--lateSurfaceViewcallback?");
return;
}
try{
cameraManager.openDriver(surfaceHolder);
//,whichcanalsothrowa
//RuntimeException.
if(handler==null){
handler=newCaptureActivityHandler(this,decodeFormats,
decodeHints,characterSet,cameraManager);
}
}catch(IOExceptionioe){
Log.w(TAG,ioe);
();
}catch(RuntimeExceptione){
//:
//java.?lang.?RuntimeException:Failtoconnecttocameraservice
Log.w(TAG,"",e);
();
}
}
privatevoid(){
AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage(getString(R.string.msg_camera_framework_bug));
builder.setPositiveButton(android.R.string.yes,newFinishListener(this));
builder.setOnCancelListener(newFinishListener(this));
builder.show();
}
@Override
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,
intheight){
}
@Override
publicvoidsurfaceCreated(SurfaceHolderholder){
if(holder==null){
Log.e(TAG,
"***WARNING***surfaceCreated()gaveusanullsurface!");
}
if(!hasSurface){
hasSurface=true;
initCamera(holder);
}
}
@Override
publicvoidsurfaceDestroyed(SurfaceHolderholder){
hasSurface=false;
}
(){
returnviewfinderView;
}
publicHandlergetHandler(){
returnhandler;
}
publicvoiddrawViewfinder(){
viewfinderView.drawViewfinder();
}
@Override
publicvoidonClick(Viewv){
switch(v.getId()){
caseR.id.capture_flashlight:
if(isFlashlightOpen){
cameraManager.setTorch(false);//關閉閃光燈
isFlashlightOpen=false;
}
else{
cameraManager.setTorch(true);//打開閃光燈
isFlashlightOpen=true;
}
break;
default:
break;
}
}
privatevoidshowErrorDialog(){
closeCamera();
viewfinderView.setVisibility(View.GONE);
AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage("掃描確認出錯,請重新掃描二維碼!");
builder.setPositiveButton(android.R.string.ok,newOnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){
restartCamera();
}
});
builder.setOnCancelListener(newOnCancelListener(){
@Override
publicvoidonCancel(DialogInterfacedialog){
CaptureCodeActivity.this.finish();
}
});
builder.show();
}
voidrestartCamera(){
Log.d(TAG,"hasSurface"+hasSurface);
viewfinderView.setVisibility(View.VISIBLE);
SurfaceViewsurfaceView=(SurfaceView)findViewById(R.id.preview_view);
SurfaceHoldersurfaceHolder=surfaceView.getHolder();
initCamera(surfaceHolder);
//恢復活動監控器
inactivityTimer.onResume();
}
voidcloseCamera(){
if(handler!=null){
handler.quitSynchronously();
handler=null;
}
inactivityTimer.onPause();
//關閉攝像頭
cameraManager.closeDriver();
}
}
在掃描出現問題事彈出dialog,當用戶點擊確定按鈕後重新開始掃描。
privatevoidshowErrorDialog(){
closeCamera();
viewfinderView.setVisibility(View.GONE);
AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage("掃描確認出錯,請重新掃描櫃子上的二維碼!");
builder.setPositiveButton(android.R.string.ok,newOnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){
restartCamera();
}
});
builder.setOnCancelListener(newOnCancelListener(){
@Override
publicvoidonCancel(DialogInterfacedialog){
CaptureCodeActivity.this.finish();
}
});
builder.show();
}