在Zxing掃描識別和圖片識別的解析對象是相同的
本文分三個步驟:
1 獲取相冊的照片
2 解析二維碼圖片
3 返回結果
1) 獲取相冊照片
google對4.4的uri做了點改動 為了適配多種手機 需要做一個判斷版本
在Activity中開啟相冊:
- IntentinnerIntent=newIntent();//"android.intent.action.GET_CONTENT"
- if(Build.VERSION.SDK_INT<19){
- innerIntent.setAction(Intent.ACTION_GET_CONTENT);
- }else{
- // innerIntent.setAction(Intent.ACTION_OPEN_DOCUMENT); 這個方法報 圖片地址 空指針;使用下面的方法
- innerIntent.setAction(Intent.ACTION_PICK);
- }
-
- innerIntent.setType("image/*");
-
- IntentwrapperIntent=Intent.createChooser(innerIntent,"選擇二維碼圖片");
-
- CaptureActivity.this
- .startActivityForResult(wrapperIntent,REQUEST_CODE);
選中了照片後返回的數據在onActivityResult方法中獲取
- @Override
- protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
-
- super.onActivityResult(requestCode,resultCode,data);
-
- if(resultCode==RESULT_OK){
-
- switch(requestCode){
-
- caseREQUEST_CODE:
-
- String[]proj={MediaStore.Images.Media.DATA};
- //獲取選中圖片的路徑
- Cursorcursor=getContentResolver().query(data.getData(),
- proj,null,null,null);
-
- if(cursor.moveToFirst()){
-
- intcolumn_index=cursor
- .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
- photo_path=cursor.getString(column_index);
- if(photo_path==null){
- photo_path=Utils.getPath(getApplicationContext(),
- data.getData());
- Log.i("123pathUtils",photo_path);
- }
- Log.i("123path",photo_path);
-
- }
-
- cursor.close();
-
- newThread(newRunnable(){
-
- @Override
- publicvoidrun(){
-
- Resultresult=scanningImage(photo_path);
- //Stringresult=decode(photo_path);
- if(result==null){
- Looper.prepare();
- Toast.makeText(getApplicationContext(),"圖片格式有誤",0)
- .show();
- Looper.loop();
- }else{
- Log.i("123result",result.toString());
- //Log.i("123result",result.getText());
- //數據返回
- Stringrecode=recode(result.toString());
- Intentdata=newIntent();
- data.putExtra("result",recode);
- setResult(300,data);
- finish();
- }
- }
- }).start();
- break;
-
- }
-
- }
-
- }
上面這段代碼
<1> 根據返回的照片信息 獲取圖片的路徑photo_path
<2> 開啟一個解析線程調用解析方法Result result = scanningImage(photo_path); 將photo_path傳進去
<3> 對返回的解析的Result對象進行判斷,獲取字符串
<4> 調用recode對result數據進行中文亂碼處理( 具體在步驟3中說明 )
- Stringrecode=recode(result.toString());
<5>這裡我將result 通過setResult(); 返回給了 父Activity
<6> Utils.getPath(getApplicationContext(),data.getData()); //將圖片Uri 轉換成絕對路徑
- publicclassUtils{
-
- publicstaticfinalbooleanisChineseCharacter(StringchineseStr){
- char[]charArray=chineseStr.toCharArray();
- for(inti=0;i //是否是Unicode編碼,除了"?"這個字符.這個字符要另外處理
- if((charArray[i]>='\u0000'&&charArray[i]<'\uFFFD')
- ||((charArray[i]>'\uFFFD'&&charArray[i]<'\uFFFF'))){
- continue;
- }else{
- returnfalse;
- }
- }
- returntrue;
- }
-
- /**
- *GetafilepathfromaUri.ThiswillgetthethepathforStorageAccess
- *FrameworkDocuments,aswellasthe_datafieldfortheMediaStoreand
- *otherfile-basedContentProviders.
- *
- *@paramcontext
- *Thecontext.
- *@paramuri
- *TheUritoquery.
- *@authorpaulburke
- */
- publicstaticStringgetPath(finalContextcontext,finalUriuri){
-
- finalbooleanisKitKat=Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT;
-
- //DocumentProvider
- if(isKitKat&&DocumentsContract.isDocumentUri(context,uri)){
- //ExternalStorageProvider
- if(isExternalStorageDocument(uri)){
- finalStringdocId=DocumentsContract.getDocumentId(uri);
- finalString[]split=docId.split(":");
- finalStringtype=split[0];
-
- if("primary".equalsIgnoreCase(type)){
- returnEnvironment.getExternalStorageDirectory()+"/"
- +split[1];
- }
-
- //TODOhandlenon-primaryvolumes
- }
- //DownloadsProvider
- elseif(isDownloadsDocument(uri)){
-
- finalStringid=DocumentsContract.getDocumentId(uri);
- finalUricontentUri=ContentUris.withAppendedId(
- Uri.parse("content://downloads/public_downloads"),
- Long.valueOf(id));
-
- returngetDataColumn(context,contentUri,null,null);
- }
- //MediaProvider
- elseif(isMediaDocument(uri)){
- finalStringdocId=DocumentsContract.getDocumentId(uri);
- finalString[]split=docId.split(":");
- finalStringtype=split[0];
-
- UricontentUri=null;
- if("image".equals(type)){
- contentUri=MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- }elseif("video".equals(type)){
- contentUri=MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
- }elseif("audio".equals(type)){
- contentUri=MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
- }
-
- finalStringselection="_id=?";
- finalString[]selectionArgs=newString[]{split[1]};
-
- returngetDataColumn(context,contentUri,selection,
- selectionArgs);
- }
- }
- //MediaStore(andgeneral)
- elseif("content".equalsIgnoreCase(uri.getScheme())){
- returngetDataColumn(context,uri,null,null);
- }
- //File
- elseif("file".equalsIgnoreCase(uri.getScheme())){
- returnuri.getPath();
- }
-
- returnnull;
- }
-
- /**
- *GetthevalueofthedatacolumnforthisUri.Thisisusefulfor
- *MediaStoreUris,andotherfile-basedContentProviders.
- *
- *@paramcontext
- *Thecontext.
- *@paramuri
- *TheUritoquery.
- *@paramselection
- *(Optional)Filterusedinthequery.
- *@paramselectionArgs
- *(Optional)Selectionargumentsusedinthequery.
- *@returnThevalueofthe_datacolumn,whichistypicallyafilepath.
- */
- publicstaticStringgetDataColumn(Contextcontext,Uriuri,
- Stringselection,String[]selectionArgs){
-
- Cursorcursor=null;
- finalStringcolumn="_data";
- finalString[]projection={column};
-
- try{
- cursor=context.getContentResolver().query(uri,projection,
- selection,selectionArgs,null);
- if(cursor!=null&&cursor.moveToFirst()){
- finalintcolumn_index=cursor.getColumnIndexOrThrow(column);
- returncursor.getString(column_index);
- }
- }finally{
- if(cursor!=null)
- cursor.close();
- }
- returnnull;
- }
-
- /**
- *@paramuri
- *TheUritocheck.
- *@returnWhethertheUriauthorityisExternalStorageProvider.
- */
- publicstaticbooleanisExternalStorageDocument(Uriuri){
- return"com.android.externalstorage.documents".equals(uri
- .getAuthority());
- }
-
- /**
- *@paramuri
- *TheUritocheck.
- *@returnWhethertheUriauthorityisDownloadsProvider.
- */
- publicstaticbooleanisDownloadsDocument(Uriuri){
- return"com.android.providers.downloads.documents".equals(uri
- .getAuthority());
- }
-
- /**
- *@paramuri
- *TheUritocheck.
- *@returnWhethertheUriauthorityisMediaProvider.
- */
- publicstaticbooleanisMediaDocument(Uriuri){
- return"com.android.providers.media.documents".equals(uri
- .getAuthority());
- }
-
- }
2) 解析二維碼圖片
- protectedResultscanningImage(Stringpath){
- if(TextUtils.isEmpty(path)){
-
- returnnull;
-
- }
- //DecodeHintType和EncodeHintType
- Hashtablehints=newHashtable();
- hints.put(DecodeHintType.CHARACTER_SET,"utf-8");//設置二維碼內容的編碼
- BitmapFactory.Optionsoptions=newBitmapFactory.Options();
- options.inJustDecodeBounds=true;//先獲取原大小
- scanBitmap=BitmapFactory.decodeFile(path,options);
- options.inJustDecodeBounds=false;//獲取新的大小
-
- intsampleSize=(int)(options.outHeight/(float)200);
-
- if(sampleSize<=0)
- sampleSize=1;
- options.inSampleSize=sampleSize;
- scanBitmap=BitmapFactory.decodeFile(path,options);
-
-
-
- RGBLuminanceSourcesource=newRGBLuminanceSource(scanBitmap);
- BinaryBitmapbitmap1=newBinaryBitmap(newHybridBinarizer(source));
- QRCodeReaderreader=newQRCodeReader();
- try{
-
- returnreader.decode(bitmap1,hints);
-
- }catch(NotFoundExceptione){
-
- e.printStackTrace();
-
- }catch(ChecksumExceptione){
-
- e.printStackTrace();
-
- }catch(FormatExceptione){
-
- e.printStackTrace();
-
- }
-
- returnnull;
- }
3) 返回結果
首先對result判斷是否為空 ,如果為空就代表 二維碼不標准或者不是二維碼圖片
在子線程中使用Toast 需要初始化looper
- Resultresult=scanningImage(photo_path);
- //Stringresult=decode(photo_path);
- if(result==null){
- Looper.prepare();
- Toast.makeText(getApplicationContext(),"圖片格式有誤",0)
- .show();
- Looper.loop();
- }else{
- Log.i("123result",result.toString());
- //Log.i("123result",result.getText());
- //數據返回
- Stringrecode=recode(result.toString());
- Intentdata=newIntent();
- data.putExtra("result",recode);
- setResult(300,data);
- finish();
- }
Result 對象返回的就是二維碼掃描的結果
調用recode(result.toString) 方法進行中文亂碼處理 代碼如下:
- privateStringrecode(Stringstr){
- Stringformart="";
-
- try{
- booleanISO=Charset.forName("ISO-8859-1").newEncoder()
- .canEncode(str);
- if(ISO){
- formart=newString(str.getBytes("ISO-8859-1"),"GB2312");
- Log.i("1234ISO8859-1",formart);
- }else{
- formart=str;
- Log.i("1234stringExtra",str);
- }
- }catch(UnsupportedEncodingExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- returnformart;
- }
處理好之後將結果字符串 返回給父Activity
對於圖片識別有些事項需要注意..
二維碼的圖標需要保證圖片盡量不傾斜 拍照的時候 最好保證手機與二維碼 水平
附圖:
-